Domanda

Ho sentito recentemente alcuni sviluppatori dire che stanno semplicemente eseguendo il polling di cose (database, file, ecc.) per determinare quando qualcosa è cambiato e quindi eseguire un'attività, come un'importazione.

Sono davvero contrario a questa idea e ritengo che l'utilizzo della tecnologia disponibile come Remoting , WCF , ecc. sarebbe molto meglio del polling.

Tuttavia, vorrei identificare i motivi per cui altre persone preferiscono un approccio rispetto all'altro e, cosa più importante, come posso convincere gli altri che il sondaggio è sbagliato in questi tempi?

È stato utile?

Soluzione

Il polling non è " errato " come tale.

Molto dipende da come viene implementato e per quale scopo. Se ti interessa davvero la notifica immediata di un cambiamento, è molto efficiente. Il codice si trova in un circuito stretto, interrogando costantemente (chiedendo) una risorsa se è stato modificato / aggiornato. Questo significa che sarai avvisato appena puoi che qualcosa è diverso. Ma il tuo codice non sta facendo altro e c'è un sovraccarico in termini di molte chiamate all'oggetto in questione.

Se sei meno interessato alla notifica immediata puoi aumentare l'intervallo tra i sondaggi e anche questo può funzionare bene, ma scegliere l'intervallo corretto può essere difficile. Troppo lungo e potresti perdere cambiamenti critici, troppo breve e sei tornato ai problemi del primo metodo.

Alternative, come interruzioni o messaggi, ecc. possono fornire un miglior compromesso in queste situazioni. Riceverai una notifica di una modifica non appena sarà praticamente possibile, ma questo ritardo non è qualcosa che controlli, dipende dal fatto che il componente stesso sia tempestivo nel trasmettere cambiamenti di stato.

Che cos'è " errato " con polling?

  • Può essere il controllo delle risorse.
  • Può essere limitante (specialmente se hai molte cose che vuoi sapere su / sondaggio).
  • Può essere eccessivo.

Ma ...

  • Non è intrinsecamente sbagliato.
  • Può essere molto efficace.
  • È molto semplice.

Altri suggerimenti

Vi sono due ragioni per cui il polling potrebbe essere considerato negativo per principio.

  1. È uno spreco di risorse. È molto probabile che verifichi una modifica mentre non si è verificata alcuna modifica. I cicli CPU / larghezza di banda spesi per questa azione non comportano cambiamenti e quindi avrebbero potuto essere spesi meglio per qualcos'altro.

  2. Il polling viene eseguito su un determinato intervallo. Ciò significa che non saprai che si è verificato un cambiamento fino alla prossima volta che l'intervallo è passato.

Sarebbe meglio essere avvisati delle modifiche. In questo modo non esegui il polling per i cambiamenti che non si sono verificati e sarai a conoscenza di un cambiamento non appena ricevi la notifica.

Esempi di cose che usano il polling al giorno d'oggi:

  • Sondaggio client e-mail per nuovi messaggi (anche con IMAP).
  • Sondaggio lettori RSS per modifiche ai feed.
  • I motori di ricerca eseguono il polling per le modifiche alle pagine che indicizzano.
  • Gli utenti di StackOverflow eseguono il polling per nuove domande, premendo "aggiorna" ;-)
  • I client Bittorrent eseguono il polling del tracker (e l'altro, credo, con DHT) per i cambiamenti nello sciame.
  • Gli spinlock su sistemi multi-core possono essere la sincronizzazione più efficiente tra i core, nei casi in cui il ritardo è troppo breve perché ci sia tempo per programmare un altro thread su questo core, prima che l'altro core faccia quello che stiamo aspettando .

A volte semplicemente non c'è modo di ricevere notifiche asincrone: ad esempio per sostituire l'RSS con un sistema push, il server dovrebbe conoscere tutti coloro che leggono il feed e avere un modo per contattarli. Questa è una mailing list - proprio una delle cose che RSS è stata progettata per evitare. Da qui il fatto che la maggior parte dei miei esempi sono app di rete, dove è più probabile che ciò costituisca un problema.

Altre volte, il polling è abbastanza economico da funzionare anche in presenza di notifiche asincrone.

Per un file locale, la notifica delle modifiche è probabilmente l'opzione migliore in linea di principio. Ad esempio, potresti (potrebbe) impedire che il disco si spenga se lo colpisci per sempre, anche se il sistema operativo potrebbe essere memorizzato nella cache. E se esegui il polling ogni secondo su un file che cambia solo una volta all'ora, potresti occupare inutilmente lo 0,001% (o qualsiasi altra cosa) della potenza di elaborazione della tua macchina. Questo suona minuscolo, ma cosa succede quando ci sono 100.000 file che devi sondare?

In pratica, tuttavia, è probabile che l'overhead sia trascurabile qualunque cosa tu faccia, il che rende difficile essere entusiasti di cambiare il codice che attualmente funziona. La cosa migliore è stare attenti ai problemi specifici che il polling causa al sistema che si desidera modificare - se ne trovate uno, sollevateli piuttosto che cercare di fare un argomento generale contro tutti i polling. Se non ne trovi, non puoi risolvere ciò che non è rotto ...

Il polling è facile da fare, molto facile, è facile come qualsiasi codice procedurale. Non effettuare il polling significa che si entra nel mondo della programmazione asincrona, che non è così facile da morire e che a volte potrebbe persino diventare una sfida.

E come per ogni cosa in qualsiasi sistema, il percorso di minore resistenza viene normalmente preso più comunemente, quindi ci saranno sempre programmatori che usano il polling, persino grandi programmatori, perché a volte non è necessario complicare le cose con schemi asincroni.

Io per primo prospero sempre per evitare il polling, ma a volte faccio comunque il polling, specialmente quando i guadagni effettivi della gestione asincrona non sono così grandi, come quando si agisce contro alcuni piccoli dati locali (ovviamente si ottiene un po 'più veloce , ma gli utenti non noteranno la differenza in un caso come questo). Quindi c'è spazio per entrambe le metodologie IMHO.

Il polling del client non viene ridimensionato così come le notifiche del server. Immagina che migliaia di clienti chiedano al server "nuovi dati"? ogni 5 secondi. Ora immagina che il server mantenga un elenco di client per notificare nuovi dati. La notifica del server si ridimensiona meglio.

Penso che le persone dovrebbero rendersi conto che nella maggior parte dei casi, a un certo livello si sta eseguendo il polling, anche in situazioni guidate da eventi o interruzioni, ma si è isolati dal codice effettivo che esegue il polling. Davvero, questa è la situazione più desiderabile ... isolati dall'attrezzo e gestisci l'evento. Anche se devi implementare tu stesso il polling, scrivi il codice in modo che sia isolato e i risultati vengano gestiti indipendentemente dall'implementazione.

È semplice - il polling è male - inefficiente, spreco di risorse, ecc. Esiste sempre una qualche forma di connettività che controlla comunque un evento di qualche tipo, anche se non viene scelto il "polling".

Quindi perché andare oltre e mettere in atto ulteriori sondaggi.

I callback sono l'opzione migliore - devi solo preoccuparti di legare il callback al tuo processo attuale. Sottostante, ci sono sondaggi in corso per vedere che la connessione è ancora in atto comunque.

Se continui a telefonare / suonare la tua ragazza e non risponde mai, perché continuare a chiamare? Lascia un messaggio e attendi fino a quando "richiama";)

Uso il polling di tanto in tanto per determinate situazioni (ad esempio, in un gioco, eseguo il polling dello stato della tastiera in ogni frame), ma mai in un ciclo che esegue SOLO il polling, piuttosto farei il polling come un controllo (ha una risorsa X modificato? Se sì, fare qualcosa, altrimenti elaborare qualcos'altro e ricontrollare più tardi). In generale, però, evito il polling a favore delle notifiche asincrone.

Il motivo è che non spendo risorse (tempo della CPU, qualunque cosa) in attesa che accada qualcosa (soprattutto se tali risorse potrebbero accelerare l'accaduto in primo luogo). I casi in cui utilizzo il polling, non rimango inattivo in attesa, utilizzo le risorse altrove, quindi è un problema (almeno per me).

Se si esegue il polling per le modifiche a un file, sono d'accordo che è necessario utilizzare le notifiche del filesystem che sono disponibili quando ciò accade, che sono disponibili nella maggior parte dei sistemi operativi ora.

In un database potresti innescare l'aggiornamento / inserire e quindi chiamare il tuo codice esterno per fare qualcosa. Tuttavia, potrebbe darsi che tu non abbia un requisito per le azioni istantanee. Ad esempio, potrebbe essere necessario ottenere i dati dal database A al database B su una rete diversa entro 15 minuti. Il database B potrebbe non essere accessibile dal database A, quindi si finisce per eseguire il polling o come programma autonomo in esecuzione vicino al database B.

Inoltre, il polling è una cosa molto semplice da programmare. Spesso è una prima implementazione eseguita quando i vincoli temporali sono brevi e, poiché funziona abbastanza bene, rimane.

La questione del polling è che funziona! È affidabile e semplice da implementare.

I costi del pooling possono essere elevati: se si esegue la scansione di un database per le modifiche ogni minuto quando vengono apportate solo due modifiche al giorno, si consumano molte risorse per un risultato molto piccolo.

Tuttavia, il problema con qualsiasi tecnologia di notifica è che sono molto più complessi da implementare e non solo possono essere inaffidabili ma (e questo è un grande MA) che non si può facilmente dire quando non funzionano.

Quindi, se si rilascia il polling per qualche altra tecnologia, assicurarsi che sia utilizzabile da programmatori medi e che sia ultra affidabile.

Vedo molte risposte qui, ma penso che la risposta più semplice sia la risposta stessa:

Perché è (di solito) molto più semplice codificare un ciclo di polling piuttosto che rendere l'infrastruttura per i callback.

Quindi, ottieni un codice più semplice che, se si rivela essere un collo di bottiglia in seguito, può essere facilmente compreso e riprogettato / riformulato in qualcos'altro.

Questo non risponde alla tua domanda. Ma realisticamente, specialmente in questo "giorno ed età" dove i cicli del processore sono economici e la larghezza di banda è grande, il polling è in realtà una soluzione abbastanza buona per alcune attività.

I vantaggi sono:

  • Cheap
  • affidabile
  • testabile
  • flessibile

Sono d'accordo che evitare il polling sia una buona politica. Tuttavia, in riferimento a Post di Robert , direi che la semplicità del polling può renderlo un approccio migliore nei casi in cui i problemi menzionati qui non sono un problema così grande, poiché l'approccio asincrono è spesso notevolmente meno leggibile e più difficile da mantenere, per non parlare dei bug che possono insinuarsi nella sua implementazione.

Come per tutto, dipende. Un grande sistema ad alta transazione su cui lavoro attualmente utilizza una notifica con SQL (una DLL caricata all'interno di SQL Server che viene chiamata da un SP esteso dai trigger su determinate tabelle. La DLL notifica quindi ad altre app che c'è lavoro da fare).

Comunque ci stiamo allontanando da questo perché possiamo praticamente garantire che ci sarà lavoro da fare continuamente. Pertanto, al fine di ridurre la complessità e velocizzare un po 'le cose, le app elaboreranno il loro lavoro e eseguiranno immediatamente il polling del DB per nuovi lavori. Se non ce n'è nessuno, ci riproverà dopo un breve intervallo.

Questo sembra funzionare più velocemente ed è molto più semplice. Tuttavia, un'altra parte dell'applicazione che ha un volume molto più basso non beneficia di un aumento della velocità usando questo metodo - a meno che l'intervallo di polling non sia molto piccolo, il che porta a problemi di prestazioni. Quindi lo stiamo lasciando com'è per questa parte. Pertanto è una buona cosa quando è appropriato, ma le esigenze di tutti sono diverse.

Ecco un buon riassunto dei meriti relativi di push and pull:   https://stpeter.im /index.php/2007/12/14/push-and-pull-in-application-architectures/

Vorrei poterlo sintetizzare ulteriormente in questa risposta, ma è meglio lasciare alcune cose senza restrizioni.

Quando si pensava al polling SQL, ai tempi del VB6 si era in grado di creare recordset usando la parola chiave WithEvents che era una prima incarnazione di asincrono " in ascolto " ;.

Personalmente cerco sempre un modo per utilizzare un'implementazione guidata dagli eventi prima del polling. In caso contrario, potrebbe essere utile un'implementazione manuale di uno dei seguenti elementi:

  • broker di servizi sql / classe di dipendenza
  • Qualche tipo di tecnologia di coda (RabbitMQ o simile)
  • Trasmissione UDP - tecnica interessante che può essere costruito con listener di più nodi. Tuttavia, non sempre è possibile su alcune opere in rete.

Alcuni di questi potrebbero richiedere una leggera riprogettazione del progetto, ma in un mondo aziendale potrebbe essere la strada migliore da percorrere piuttosto che un servizio di polling.

Concorda con la maggior parte delle risposte che Async / Messaging è in genere migliore. Sono assolutamente d'accordo con la risposta di Robert Gould. Ma vorrei aggiungere un altro punto.

Un'aggiunta è che il polling può uccidere due uccelli con una fava. In un caso d'uso particolare, un progetto a cui sono stato coinvolto ha utilizzato una coda di messaggi tra database ma il polling da un server delle applicazioni a uno dei database. Poiché la rete dal server delle app al DB era occasionalmente inattiva, il polling è stato inoltre utilizzato per segnalare problemi di rete all'app.

Alla fine, usa ciò che ha più sensato per il caso d'uso tenendo presente la capacità di ridimensionamento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top