Forum: Italian Ruby user group Capybara due sessioni in parallello

Posted by michele boscolo (sphynx)
on 2012-06-15 11:10
Ciao a tutti e buon Ruby Day :), vi scrivo per un problema al momento
insormontabile per me, vorrei lanciare due sessioni in parallelo con
capybara e il driver Chrome,inserendole in due Thread differenti, ma
quando lancio il mio codice partono tutte e due contemporaneamente, ma
al momento di interagire, prosegue solo su una sessione, devo chiuderla
manualmente e parte anche l'altra, io vorrei venissere eseguite in
parallelo.

Ho fatto dei test anche lanciado due processi separati, non con i
Thread, ma si verifica lo stesso probleme.

Spero possiate aitutarmi, grazie, di seguito il codice:

http://pastebin.com/RxEQytiz
Posted by Matteo Collina (Guest)
on 2012-06-15 12:53
(Received via mailing list)
Il giorno 15 giugno 2012 11:10, michele boscolo <miboscol@gmail.com> ha
scritto:

>
> Spero possiate aitutarmi, grazie, di seguito il codice:
>
> http://pastebin.com/RxEQytiz


Posso chiederti perch vuoi farlo?
Usare i Thread nei test  veramente veramente una bad practice.

Secondo me il problema  con Selenium, che supporta una sola istanza alla
volta.
Prova con capybara-webkit o con zombiejs.

Ciao,

Matteo
Posted by gabriele renzi (Guest)
on 2012-06-15 13:15
(Received via mailing list)
2012/6/15 Matteo Collina <matteo.collina@gmail.com>:

> Posso chiederti perch vuoi farlo?
> Usare i Thread nei test  veramente veramente una bad practice.


beh a meno di voler fare uno smoke test per qualcosa che dovrebbe
essere thread safe :)


--
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com
Posted by michele boscolo (sphynx)
on 2012-06-15 16:00
Voleve farlo per velocizzare il processo, perchè sto realizando uno 
spider per raccogliere dei prezzi della borsa elettrica di divesri 
paesi.
Sono riuscito a raccogliere i prezzi di tutte le frontiere con 
Mechanize, che ha una velocità disarmante, ma non supportando 
javascript, ho provato con capybara-webkit, mi da sempre problemi con il 
javascript, allora  ho utilizzato capyraba con selenium(driver chrome), 
quindi questo sito è il collo di bottiglia del mio programma, in quanto 
a scaricare i prezzi di 7 frontiere ci mette 4 secondi, invece solo per 
questo sito ci mette quasi 2 minuti, e mi dispiace.

Spero che qualcuno posso aiutarmi, oppure conoscete qualcosa come 
Mechanize ma che funzioni anche con il javascript??

Grazie.
Posted by gabriele renzi (Guest)
on 2012-06-16 19:09
(Received via mailing list)
2012/6/15 michele boscolo <miboscol@gmail.com>:
> Voleve farlo per velocizzare il processo, perch sto realizando uno
> spider per raccogliere dei prezzi della borsa elettrica di divesri
> paesi.
> Sono riuscito a raccogliere i prezzi di tutte le frontiere con
> Mechanize, che ha una velocit disarmante, ma non supportando
> javascript, ho provato con capybara-webkit, mi da sempre problemi con il
> javascript, allora ho utilizzato capyraba con selenium(driver chrome),
> quindi questo sito  il collo di bottiglia del mio programma, in quanto
> a scaricare i prezzi di 7 frontiere ci mette 4 secondi, invece solo per
> questo sito ci mette quasi 2 minuti, e mi dispiace.

se il problema  che non va in multithread, hai provato a farlo 
multiprocesso?


--
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com
Posted by gabriele renzi (Guest)
on 2012-06-16 19:12
(Received via mailing list)
2012/6/16 gabriele renzi <rff.rff@gmail.com>:
>> questo sito ci mette quasi 2 minuti, e mi dispiace.
altra alternativa a capybara-*, forse (fire)watir?



--
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com
Posted by michele boscolo (sphynx)
on 2012-06-17 08:21
Ciao a tutti, grazie dei consigli, ma alla fine sono riuscito a 
risolvere con capybara-webkit, ora in 13 sec. riesco a scaricare tutto, 
una figata.

Scusa una curiosità, ma cosa intendevi "farlo multiprocesso"???

Per Gabriele "(fire)watir" è ottimo ho sempre usato questo per fare i 
miei spider, ma è lento, perchè lavora con il browser, mentre se lavori 
con mechanize o capybara, oppure fai il trace delle richieste http post, 
e poi le esegui in ruby, è tutto molto più rapido, ti scrolli di dosso 
la GUI, che appesantisce il tutto.

Ciao, grazie ancora.
Posted by gabriele renzi (Guest)
on 2012-06-17 11:18
(Received via mailing list)
2012/6/17 michele boscolo <miboscol@gmail.com>:
> Ciao a tutti, grazie dei consigli, ma alla fine sono riuscito a
> risolvere con capybara-webkit, ora in 13 sec. riesco a scaricare tutto,
> una figata.
>
> Scusa una curiosit, ma cosa intendevi "farlo multiprocesso"???


intendevo: se c'era un problema dovuto al fatto che capybara-webkit
non funzionasse in ambiente multithread a causa di qualche stato
condiviso,  potevi provare con i processi.

Ma rileggendo il thread mi sono accorto che gi avevi detto di averci
provato, sono uno scemo scusami...

Ad ogni modo, se hai identificato il problema, come hai risolto?
Cos almeno rimane nell'archivio della lista (e mis che fra un po'
servir anche a me :)


--
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com
Posted by michele boscolo (sphynx)
on 2012-06-18 09:29
Ciao, senza allegarti tutto il programma che contine abbastanza 
codice,ti allego un esempio di come ho risolto il problema:

Avvio.rb
_________________________________________

pipe  = IO.popen("rubyw capyraba.rb google",'r')
pipe2 = IO.popen("rubyw capyraba.rb bing",'r')
Process.wait

Capybara.rb
_________________________________________
require 'capybara/dsl'
require 'capybara-webkit'

Capybara.run_server = false
Capybara.current_driver = :webkit

module Test
  class Google
    include Capybara::DSL

    def get_results(site)
      if "google" == site
      Capybara.instance_variable_set('@app_host',"http://www.google.com/")
      visit('/')
      fill_in "q", :with => "Capybara"
      click_button "Cerca con Google"
      click_link("Wikipedia, the free encyclopedia")
      page.driver.render "mio.png"
      else
      Capybara.instance_variable_set('@app_host',"http://it.bing.com/")
      visit('/')
      fill_in "q", :with => "Rails"
      click_button "sb_form_go"
      click_link("Ruby on Rails - Wikipedia")
      page.driver.render "mio2.png"
      end
    end
  end
end

site = ARGV[0]
spider = Test::Google.new
spider.get_results(site)


Avevo provato a farlo multithread, ma  generava errori, che vista 
mancanza tempo non sono riuscito a risolvere, quindi l'ho fatto con i 
processi.

Ciao.
Posted by gabriele renzi (Guest)
on 2012-06-18 11:18
(Received via mailing list)
On Mon, Jun 18, 2012 at 9:29 AM, michele boscolo <miboscol@gmail.com> 
wrote:
> Ciao, senza allegarti tutto il programma che contine abbastanza
> codice,ti allego un esempio di come ho risolto il problema:

<snip>
grazie, sembra ragionevole e pi o meno come avrei pensato di farlo
io, a parte che pensavo di usare DRb per far comunicare i processi :)


--
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com
Posted by michele boscolo (sphynx)
on 2012-06-19 23:23
Ciao, mi ha incuriosito quello che hai detto, mi potresti fare un 
piccolo codice d'esempio su come far comunicare diversi processi tra 
loro??
E poi volevo un vostro parere, su cosa sia più performante tra il 
lanciare diversi processi che eseguono particolari parti di codice più 
lento tipo IO lento, oppure usare i Thread oppure ancora usare un 
sistema come Eventmachine che fa uso dei Fiber??

In altre parole vorrei sapere, secondo voi quale sia la strada migliore 
da intraprendere per un'applicativo, con molto IO, quindi tempi d'attesa 
lunghi, non mi interessa il fatto che debba gestire  molte connessioni 
contemporaneamente, deve solo eseguire una serie di operazioni nel minor 
tempo possibile, e che dia la possibilità di gestire gli errori in caso 
ce ne fossero.

Grazie a tutti ciao.
Posted by gabriele renzi (Guest)
on 2012-06-20 11:15
(Received via mailing list)
2012/6/19 michele boscolo <miboscol@gmail.com>:
> Ciao, mi ha incuriosito quello che hai detto, mi potresti fare un
> piccolo codice d'esempio su come far comunicare diversi processi tra
> loro??

DRb  facilissimo:

# server.rb
require 'drb'

# crea una classe, magari usando delle strutture dati sensate :)
QueueManager = Struct.new :queued, :visited do
    def next_url
      queued.shift
    end
    def save url, content, new_links
      p "#$0: saving visited #{url}"
      visited << [url, content]
      self.queued = new_links + queued
    end
end

# rendila distribuita
DRb.start_service nil, QueueManager.new(['origin'], [])

# stampa lo uri di bind
puts DRb.uri

#loop forever
DRb.thread.join

.....

#client.rb
require 'drb'
# connettiti allo uri passato da command line
queue_manager = DRbObject.new nil, ARGV.shift

#implementa la tua logica
def visit url
  sleep rand(5)
  p "#$0: visiting #{url}"
  ['some content', [rand.to_s, 'new_links']]
end
# gira in eterno, invocando i metodi remoti come se fosser locali
while true
  url = queue_manager.next_url
  queue_manager.save(url, *visit(url))
end

....

Se vuoi gestire errori/retry/politeness/priority.. diventa pi complicato 
:)

> E poi volevo un vostro parere, su cosa sia pi performante tra il
> lanciare diversi processi che eseguono particolari parti di codice pi
> lento tipo IO lento, oppure usare i Thread oppure ancora usare un
> sistema come Eventmachine che fa uso dei Fiber??

Evented io, quindi event machine o simili, perch rischi spesso che un
thread/processo si piombi ad aspettare su una connessione di rete, e
generalmente avere 1000+ thread o processi  pesantuccio. Ma neanche
cos tanto, con i computer attuali.

In compenso non scali a pi macchine.. in quel caso, N processi
fetcher tutti con event loop, e un master controller che fa
distribuzione dei task secondo me  la soluzione "giusta".


In generale la cosa che ti migliora un sacco le prestazioni  mettere
una cache per il dns :)



> In altre parole vorrei sapere, secondo voi quale sia la strada migliore
> da intraprendere per un'applicativo, con molto IO, quindi tempi d'attesa
> lunghi, non mi interessa il fatto che debba gestire molte connessioni
> contemporaneamente, deve solo eseguire una serie di operazioni nel minor
> tempo possibile, e che dia la possibilit di gestire gli errori in caso
> ce ne fossero.

pi connessioni rendono pi efficiente l'uso della banda, e gestire
gli errori  pi facile in un single thread, single process.
Il problema  se puoi farlo con le librerie che usi, e.g. se puoi
fetchare l'html con typheous e poi passarlo al motore webkit come
stringa, allora direi fai quello.



--
twitter: @riffraff
blog (en, it): www.riffraff.info riffraff.blogsome.com
work: circleme.com
Posted by michele boscolo (sphynx)
on 2012-06-20 23:54
Grazie mille per la rapida risposta, mi hai dato un ottimo spunto per 
alcuni miei progetti, vorrei segnalare anche questa ottima guida all'uso 
di drb, la trovo eccezionale e per di più è in italiano.

http://code.google.com/p/hackerarena/wiki/RelationWikiPage.

Inoltre mi confermi il fatto che più processi, vengono eseguiti 
contemporaneamente dalle cpu, quindi viene sfruttato a pieno i 
processori multicore, perchè viene usato lo schedule del so.

Ciao.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.