Thread pooling per task molto lunghi

24 views
Skip to first unread message

Emmanuele Sordini

unread,
Nov 19, 2012, 4:59:03 AM11/19/12
to jug-g...@googlegroups.com
Ciao a tutti,
in una mia applicazione web ho necessita' di gestire dei thread che lanciano task di elabpanche molto lunghi (anche diversi giorni!).

La prima soluzione che ho provato e' stato usare i thread pool offerto dal package java.util.concurrent. Questa soluzione ha si' il grosso vantaggio di essere "gratis" (poche righe di codice e sei in pista), ma per contro offre limitate possibilita'  di controllo, monitoraggio ed eventualmente distruzione dei thread. Me ne sono accorto a mie spese perche' alcune elaborazioni che lancio (che fanno di utilizzo anche di chiamate remote, come RMI o CORBA) magari stanno in piedi per una o due ore e poi muoiono senza che io sia in grado di capire che cosa sia successo.

Quindi la mia domanda e': sapete se esistono soluzioni/toolkit che riescano ad offrirmi un controllo maggiore alla luce delle esigenze di cui sopra, se possibile senza introdurre troppa complicazione a livello di codice?

Grazie in anticipo,
Emmanuele


Fabrizio Giudici

unread,
Nov 19, 2012, 5:06:59 AM11/19/12
to jug-g...@googlegroups.com, Emmanuele Sordini
On Mon, 19 Nov 2012 10:59:03 +0100, Emmanuele Sordini
<emmanuel...@gmail.com> wrote:


> Quindi la mia domanda e': sapete se esistono soluzioni/toolkit che
> riescano
> ad offrirmi un controllo maggiore alla luce delle esigenze di cui sopra,
> se
> possibile senza introdurre troppa complicazione a livello di codice?

Mmmmhhhh... ci sono anche alternative, ma se per "maggior controllo"
intendi il problema dei thread che muoiono, no, credo che la cosa richieda
più indagine da parte tua. La Concurrency API è considerata piuttosto
buona. Da quel che scrivi, sembrerebbe che ti mangi un'eccezione.

--
Fabrizio Giudici - Java Architect @ Tidalwave s.a.s.
"We make Java work. Everywhere."
http://tidalwave.it/fabrizio/blog - fabrizio...@tidalwave.it

Corrado Leoncini

unread,
Nov 19, 2012, 5:08:27 AM11/19/12
to Jug Genova
Prova questa è una piattaforma più che una soluzione, ma quando la usavo funzionava decentemente:


Ciao, Corrado..






--
Hai ricevuto questo messaggio perché sei iscritto al gruppo "jug-genova" di Google Gruppi.
Per postare messaggi in questo gruppo, invia un'email a jug-g...@googlegroups.com.
Per annullare l'iscrizione a questo gruppo, invia un'email a jug-genova+...@googlegroups.com.
Per ulteriori opzioni, visita il gruppo all'indirizzo http://groups.google.com/group/jug-genova?hl=it.

Emmanuele Sordini

unread,
Nov 19, 2012, 5:15:37 AM11/19/12
to jug-g...@googlegroups.com



2012/11/19 Fabrizio Giudici <Fabrizio...@tidalwave.it>


Mmmmhhhh... ci sono anche alternative, ma se per "maggior controllo" intendi il problema dei thread che muoiono, no, credo che la cosa richieda più indagine da parte tua. La Concurrency API è considerata piuttosto buona. Da quel che scrivi, sembrerebbe che ti mangi un'eccezione.

Effettivamente ci sono due aspetti molto diversi, che pero' mi interessano in egual misura. Per "maggior controllo" intendo dire:

1) Possibilita' di interrogare un thread in qualunque momento per chiedegli "che cosa sta facendo", cioe' ad es. se e' attivo oppure no (polling), oppure generare degli eventi tipo callback alla fine dell'esecuzione normale se si verifica qualche anomalia (quindi non polling, ma gestione ad eventi o comunque asincrona);

2) Possibilita' di interrompere l'esecuzione di un thread in qualunque momento e ripulire le relative risorse;

Per quanto concerne invece lo specifico problema dei thread "scomparsi", non so davvero come fare, perche' ho messo i log al massimo ma non e' sufficiente, perche' il thread muore senza lasciare traccia apparente. L'unico modo sarebbe mettere un breakpoint ma se devo aspettare 2h per fare un solo test, vado poco lontano... :-(

Grazie
Emmanuele

Carlo Bonamico

unread,
Nov 19, 2012, 5:22:51 AM11/19/12
to jug-g...@googlegroups.com
Ciao, 
 quello che valuterei se sonmo processi molto lunghi, è se serve che sian thread oppure non sia meglio che sianmo veri e propri processi... 
Puoi trovare delle idee anche nel modo in cui jenkins gestisce la schedulazione/monitoing dei task/build, o addirittura in certi ambiti specifici io in passato ho anche utilizzato jenkins come esecutore di task, pilotabile poi tramite API rest.

Altra cosa da approfondire potrebbe essere

A presto
Carlo

2012/11/19 Emmanuele Sordini <emmanuel...@gmail.com>

--
Hai ricevuto questo messaggio perché sei iscritto al gruppo "jug-genova" di Google Gruppi.
Per postare messaggi in questo gruppo, invia un'email a jug-g...@googlegroups.com.
Per annullare l'iscrizione a questo gruppo, invia un'email a jug-genova+...@googlegroups.com.
Per ulteriori opzioni, visita il gruppo all'indirizzo http://groups.google.com/group/jug-genova?hl=it.



--
Carlo Bonamico
Solution Architect & Senior Trainer
NiS Network Integration and Solutions S.r.l.
carlo.b...@nispro.it - www.nispro.it
Via Al Porto Antico 7 - 16128 GENOVA 
Tel. 0105954946 Fax 0108680159
Mobile: 340 3304192

--
NOTA DI RISERVATEZZA:
Questa e-mail, con i relativi allegati, contiene informazioni da considerarsi strettamente riservate, ed è destinata esclusivamente al destinatario sopra indicato, il quale è l'unico autorizzato ad usarlo, copiarlo e, sotto la propria responsabilità, diffonderlo.
Chiunque ricevesse questo messaggio per errore è pregato di notificarcelo via e-mail, e distruggere questo messaggio.

CONFIDENTIAL NOTE:
This e-mail, together with its annexes, contains information to be deemed strictly confidential and is destined only to the address(es) identified above who only may use, copy and, under his/their responsibility, further disseminate it.
If you are not the intended recipient, please immediately notify us by e-mail and delete this message.

Fabrizio Giudici

unread,
Nov 19, 2012, 5:34:57 AM11/19/12
to jug-g...@googlegroups.com, Emmanuele Sordini
On Mon, 19 Nov 2012 11:15:37 +0100, Emmanuele Sordini
<emmanuel...@gmail.com> wrote:

> Effettivamente ci sono due aspetti molto diversi, che pero' mi
> interessano
> in egual misura. Per "maggior controllo" intendo dire:
>
> 1) Possibilita' di interrogare un thread in qualunque momento per
> chiedegli
> "che cosa sta facendo", cioe' ad es. se e' attivo oppure no (polling),

Non basta Thread.isAlive()?

> oppure generare degli eventi tipo callback alla fine dell'esecuzione
> normale se si verifica qualche anomalia (quindi non polling, ma gestione
> ad

Qui potresti trovare qualcosa, ma personalmente preferisco mettere una
bella try / catch (Throwable) con logging nel Runnable a monte di tutto.
In questo modo sono sicuro di quello che sta succedendo.

> eventi o comunque asincrona);
>
> 2) Possibilita' di interrompere l'esecuzione di un thread in qualunque
> momento e ripulire le relative risorse;

Per quanto ne so è impossibile, come da specifiche della JVM (vedi
commenti su Thread.stop() deprecato). La terminazione di un thread deve
essere sempre collaborativa (alzare flag e il Thread deve periodicamente
verificare il flag ed eventualmente fermare quello che sta facendo).

>
> Per quanto concerne invece lo specifico problema dei thread "scomparsi",
> non so davvero come fare, perche' ho messo i log al massimo ma non e'
> sufficiente, perche' il thread muore senza lasciare traccia apparente.
> L'unico modo sarebbe mettere un breakpoint ma se devo aspettare 2h per
> fare
> un solo test, vado poco lontano... :-(

Ma hai anche provato la try / catch (Throwable)?

Comunque, aggiungo alla lista dei consigli Quartz. L'idea di Carlo di
usare processi (Java) esterni non è male (credo ti faciliterebbe la
gestione di uno stop con pulizia delle risorse, perché basterebbe killare
il processo), dipende ovviamente da quello che si vuol fare.

Emmanuele Sordini

unread,
Nov 19, 2012, 6:03:49 AM11/19/12
to jug-g...@googlegroups.com



2012/11/19 Fabrizio Giudici <Fabrizio...@tidalwave.it>

Non basta Thread.isAlive()?

No, perche' col thread pool non hai accesso al singolo thread.

Inoltre il thread rimane appeso per TUTTO il tempo di durata dell'elaborazione, aprendo una chiamata remota che puo' durare ore o giorni prima di terminare. Da notare che non ho diretto controllo sull'oggetto chiamato via remoto, che e' roba fornita da terze parti di cui non ho il sorgente. Quindi lato server *non* mi e' possibile implementare il soddisfacimento delle richieste in modo piu' intelligente.
 

Per quanto ne so è impossibile, come da specifiche della JVM (vedi commenti su Thread.stop() deprecato). La terminazione di un thread deve essere sempre collaborativa (alzare flag e il Thread deve periodicamente verificare il flag ed eventualmente fermare quello che sta facendo).

Questo e' un casino, purtroppo, per come sono fatte le chiamate (v. sopra).


Ma hai anche provato la try / catch (Throwable)?

Solo catch (Exception): magari il problema sta proprio qui. Ci provo.

Comunque, aggiungo alla lista dei consigli Quartz. L'idea di Carlo di usare processi (Java) esterni non è male (credo ti faciliterebbe la gestione di uno stop con pulizia delle risorse, perché basterebbe killare il processo), dipende ovviamente da quello che si vuol fare.

L'idea di usare processi esterni ha indubbiamente i suoi vantaggi, ma secondo me complica un po' troppo le cose a livello di codice. La criticita' dei task Java sta infatti nella loro durata, e non nella quantita' di risorse richieste alla JVM.

Emmanuele

Fabrizio Giudici

unread,
Nov 19, 2012, 6:16:42 AM11/19/12
to jug-g...@googlegroups.com, Emmanuele Sordini
On Mon, 19 Nov 2012 12:03:49 +0100, Emmanuele Sordini
<emmanuel...@gmail.com> wrote:

> 2012/11/19 Fabrizio Giudici <Fabrizio...@tidalwave.it>
>
>>
>> Non basta Thread.isAlive()?
>>
>
> No, perche' col thread pool non hai accesso al singolo thread.

Ma il Runnable che viene eseguito sì.

> Inoltre il thread rimane appeso per TUTTO il tempo di durata
> dell'elaborazione, aprendo una chiamata remota che puo' durare ore o
> giorni
> prima di terminare. Da notare che non ho diretto controllo sull'oggetto
> chiamato via remoto, che e' roba fornita da terze parti di cui non ho il
> sorgente. Quindi lato server *non* mi e' possibile implementare il
> soddisfacimento delle richieste in modo piu' intelligente.

> Solo catch (Exception): magari il problema sta proprio qui. Ci provo.

Tipicamente può essere un OutOfMemoryError, magari del PermGen, che non
becchi se non con il throwable.

> L'idea di usare processi esterni ha indubbiamente i suoi vantaggi, ma
> secondo me complica un po' troppo le cose a livello di codice. La
> criticita' dei task Java sta infatti nella loro durata, e non nella
> quantita' di risorse richieste alla JVM.

Attenzione che se non vedi il processo remoto, l'errore potrebbe stare là
dentro e poi ti viene ribaltato sul chiamante.

Da quello che mi dici, io ho paura che il problema stia nella famigerata
chiamata remota, che è un mostrillo. Non devono esistere chiamate remote
così lunghe, ci vorrebbe una cosa asincrona in questi casi, ma se
l'oggetto remoto non è modificabile, è un bel casino.

Giampaolo Melis

unread,
Nov 19, 2012, 6:55:53 AM11/19/12
to JUG Genova, Emmanuele Sordini
Concordo. Se non hai il controllo del codice remoto e del codice che effettua le chiamate remote, io seguirei il consiglio di Carlo sui processi fuori dalla JVM: per esperienza e' l'unico metodo che ti salva da ore e ore di debug e profiling.
Se invece hai il controllo sul chiamante delle procedure remote non e' detto che l'approccio a tp non funzioni.
Di solito quando ho task lunghi e che lavorano principalmente su I/O uso i pool con oggetti di tipo SwingWorker
(ad es. SeingWorker di jdesktop o anche Task di swing application framework).
In questo modo ho sia un lifecycle (metodi doInBackground, done, ...) sia un po' di infrastruttura per mettere in piedi un controllo del progress via eventi. Inoltre in questi casi, visto che i metodi bloccanti del task lungo sono di solito attese efficenti, ho anche l'arma del thread interrupt (a patto di gestire correttamente l'uscita per InterruptedException).
Ciao.

Giampaolo
 
2012/11/19 Fabrizio Giudici <Fabrizio...@tidalwave.it>
--
Hai ricevuto questo messaggio perché sei iscritto al gruppo "jug-genova" di Google Gruppi.
Per postare messaggi in questo gruppo, invia un'email a jug-g...@googlegroups.com.
Per annullare l'iscrizione a questo gruppo, invia un'email a jug-genova+unsubscribe@googlegroups.com.

Emmanuele Sordini

unread,
Nov 19, 2012, 7:41:45 AM11/19/12
to jug-g...@googlegroups.com
2012/11/19 Fabrizio Giudici <Fabrizio...@tidalwave.it>


Ma il Runnable che viene eseguito sì.

Si', certo. Ma per rispondermi correttamente non deve avere tipo un flag di stato? Se il Runnable eseguito si appende nell'esecuzione del suo metodo run() finche' l'esecuzione non termina, non so quanto abbia senso chiamare isAlive()...

Attenzione che se non vedi il processo remoto, l'errore potrebbe stare là dentro e poi ti viene ribaltato sul chiamante.
Da quello che mi dici, io ho paura che il problema stia nella famigerata chiamata remota, che è un mostrillo. Non devono esistere chiamate remote così lunghe, ci vorrebbe una cosa asincrona in questi casi, ma se l'oggetto remoto non è modificabile, è un bel casino.

Per fare un esempio concreto, uno dei task remoti che la mia webapp deve controllare e' uno script in Matlab di cui ho il sorgente. Questo script Matlab eseguito da dentro il suo ambiente funziona bene e termina correttamente dopo alcune ore. Il fatto che io abbia il codice Matlab pero' non mi aiuta affatto dal punto di vista della gestione degli errori, dato che Matlab e' un ambiente runtime a se stante, sul cui funzionamento interno di basso livello (tipo, appunto, la gestione delle chiamate remote) io non ho *nessun* controllo.

Forse potrebbe essermi d'aiuto l'utilizzo di un accoppiamento piu' "lasco", tipo gestore dei job funzionante sullo stesso server dove i programmi Matlab vengono eseguiti (che e' diverso dal server su cui gira l'applicazione web). Ma data la notevole complessita' di una soluzione del genere (alla fine dell'esecuzione l'applicazione produce dei risultati che devono essere presi e archiviati dall'applicazione web), volevo riservarmela veramente come ultimissima spiaggia.


2012/11/19 Fabrizio Giudici <Fabrizio...@tidalwave.it>

Emmanuele Sordini

unread,
Nov 19, 2012, 7:42:04 AM11/19/12
to jug-g...@googlegroups.com



2012/11/19 Giampaolo Melis <giampao...@gmail.com>

Emmanuele Sordini

unread,
Nov 19, 2012, 7:44:55 AM11/19/12
to Giampaolo Melis, JUG Genova



2012/11/19 Giampaolo Melis <giampao...@gmail.com>

Concordo. Se non hai il controllo del codice remoto e del codice che effettua le chiamate remote, io seguirei il consiglio di Carlo sui processi fuori dalla JVM: per esperienza e' l'unico metodo che ti salva da ore e ore di debug e profiling.
Se invece hai il controllo sul chiamante delle procedure remote non e' detto che l'approccio a tp non funzioni.

Si', ho il pieno controllo del codice chiamante, ma non del chiamato, almeno non nel senso di poter modificare il modo in cui le chiamate remote sono gestite dal server.

Di solito quando ho task lunghi e che lavorano principalmente su I/O uso i pool con oggetti di tipo SwingWorker
(ad es. SeingWorker di jdesktop o anche Task di swing application framework).
In questo modo ho sia un lifecycle (metodi doInBackground, done, ...) sia un po' di infrastruttura per mettere in piedi un controllo del progress via eventi. Inoltre in questi casi, visto che i metodi bloccanti del task lungo sono di solito attese efficenti, ho anche l'arma del thread interrupt (a patto di gestire correttamente l'uscita per InterruptedException).

Grazie, cerco di approfondire l'argomento.

Emmanuele

Andrea Leoncini

unread,
Nov 20, 2012, 5:24:40 AM11/20/12
to jug-g...@googlegroups.com
magari sbaglio ma dagli interessi che stai indicando sembra che tu stia cercando funzionalita' tipiche di un sistema di process management

mi spiego meglio, ti preoccupi del fatto che ci siano thread che non fanno niente, quindi immagino che stiano aspettando che qualcuno faccia qualcosa, poi leggo che vuoi interrompere dei thread, quindi forse vuoi sospendere/eliminare il batch (o processo) in esecuzione.

insomma tutte queste cose le hai a disposizione e le gestisci facilmente disegnado un workflow del tuo batch e demandando l'esecuzione ad un apposito engine.

nel caso:

http://www.jboss.org/jbpm

saluti andrea


2012/11/19 Emmanuele Sordini <emmanuel...@gmail.com>

--
Hai ricevuto questo messaggio perché sei iscritto al gruppo "jug-genova" di Google Gruppi.
Per postare messaggi in questo gruppo, invia un'email a jug-g...@googlegroups.com.
Per annullare l'iscrizione a questo gruppo, invia un'email a jug-genova+...@googlegroups.com.

Per ulteriori opzioni, visita il gruppo all'indirizzo http://groups.google.com/group/jug-genova?hl=it.



--
Andrea Leoncini
----------------------------
Esse Quam Videri

Emmanuele Sordini

unread,
Nov 23, 2012, 5:55:59 AM11/23/12
to JUG Genova



2012/11/20 Andrea Leoncini <andrea....@gmail.com>

magari sbaglio ma dagli interessi che stai indicando sembra che tu stia cercando funzionalita' tipiche di un sistema di process management

mi spiego meglio, ti preoccupi del fatto che ci siano thread che non fanno niente, quindi immagino che stiano aspettando che qualcuno faccia qualcosa, poi leggo che vuoi interrompere dei thread, quindi forse vuoi sospendere/eliminare il batch (o processo) in esecuzione.

Il mio pone diverse problematiche, riassumibili come segue:

1) Esecuzione remota di job: la web application (che in questo caso rappresenta il client) e il software che esegue il job stanno fisicamente su server diversi (ma sulla stessa rete, ovviamente)

2) Gli ambienti di esecuzione del job sono eterogenei e NON scritti in Java (es. Matlab), per cui si pongono dei problemi di controllo, che deve essere necessariamente basato sul lancio eseguibili (che quindi, in effetti, diventano dei processi) piuttosto che sull'invocazione di oggetti distribuiti

3) L'esecuzione dei job di calcolo tipicamente puo' durare anche molte ore o anche a molti giorni; a volte potrebbe esserci la necessita' di interrompere/ammazzare un processo 


insomma tutte queste cose le hai a disposizione e le gestisci facilmente disegnado un workflow del tuo batch e demandando l'esecuzione ad un apposito engine.

Ho dato un'occhiata e l'idea e' interessante. Tuttavia, pur essendo pertinente alle mie problematiche, ho la vaga impressione che la "sovrastruttura" di progettazione del workflow e gestione dei processi sia un po' troppo ad "alto livello" rispetto alle mie esigenze. Comunque approfondiro' l'argomento.

Grazie,
Emmanuele


Carlo Bonamico

unread,
Nov 23, 2012, 6:06:48 AM11/23/12
to jug-g...@googlegroups.com

Un altra ipotesi è passare ad utilizzare una interazione a messaggi asincroni tipo jms ad inizio e fine attività.

Reply all
Reply to author
Forward
0 new messages