Ok. Wegen meiner vorherigen Vermutung noch eine Frage: Ist es so, dass der
Webservice, den Du ansprichst, ebenfalls auf Deinem localhost läuft? So
hatte ich Deine erste Schilderung vestanden. Dass Du mittels eines
net/http-objektes ebenfalls Deine eigenen mongrels ansprichst. Sicher, dass
macht auf den ersten Blick keinen Sinn, aber - das wissen wir alle -
manchmal geht man seltsame Wege. Dann hätte es nämlich so sein können, dass
Deine requests aus dem net/http-Objekt Deine eigenen mongrels blockieren.
Was passiert denn im Log? Wird da wirklich nur einer der acht mongrels von
dem net/http-Kram blockiert? Wenn das so ist kann der Fehler ja eigentlich
nur im Load-Balancing liegen, ansonsten müssten die anderen mongrels
requests beantworten.
Gruß
Jan
Am 25. August 2008 14:05 schrieb Jan Roesner <[EMAIL PROTECTED]>:
> Hallo Jan,
>
> Jan Prill schrieb:
> > Hi Jan,
> > vielleicht kannst Du den net/http-Aufruf einmal darstellen.
> >
> > Du schreibst, dass das net/http Object EINIGE Anfragen im Hintergrund
> > absetzt. Sind dies mehr als acht Anfragen? Setze doch mal jeweis eine
> > Anfrage ab und schließe den request dann einmal korrekt. Vielleicht
> bleibt
> > der geöffnete request "offen" bis alle Anfragen beendet sind und
> blockiert
> > solange auch den mongrel. Meine Vermutung ist, dass sehr schnelle alle
> > mongrel-instanzen belegt sind bis das net/http-Objekt geschlossen wird.
>
> Also wenn ich die Action aufrufe, wird tatsächlich immer nur ein
> net/http Object instanziert. Die Funktionen dazu sehen ungefähr so aus:
>
> # es gibt Users mit Benutzername und Passwort für je einen WebService
> # weiterhin gibt es den Table UserConditions mit User has many
> UserConditions
> # Benutzername und Passwort wird nun nach dem Aufruf samt Service ID
> an eine protected Action übergeben
>
> def do_my_very_important_stuff
> @user_condition = UserCondition.find(params[:id])
>
> @user_condition.status = get_query_result(@user_condition.user.name,
> @user_condition.user.password, @user_condition.service_id)
> @user_condition.save!
> respond_to do |format|
> format.js
> end
> end
>
> # protected Action
>
> def get_query_result(username, password, service_id)
> @service = Service.find(service_id)
> @item_list = get_item_list(12,18) # returniert eine Liste mit 12 bis
> 18 items
>
> # holt sich dynamisch eine Instanz vom Service Object, das genauere
> Daten zum anzusprechenden WebService enthält
> # nicht schön, ich weiss ...
> eval("@service_runner = [EMAIL PROTECTED](username,
> password, service_id)")
> status = nil
>
> # erst der Login am Service
> if @service_runner.login
> logger.warn("Successfully logged in")
> @error = false
> for item in @item_list
> # dann die eigentliche Action am WebService
> if not @service_runner.do_stuff_with(item)
> logger.warn("!!! runner for item #{item} returned with an
> error, aborting")
> @error = true
> break
> end
> end
> if not @error
> status = 'do_stuff_with returned successfully'
> else
> logger.warn("!!! do_stuff_with returned with errors")
> status = 'do_stuff_with failed'
> end
> else
> logger.warn("Error while logging in")
> status = 'login failed'
> end
> return status
> end
>
>
> Und ein einfaches Object sieht in etwa so aus, auch dirty, aber die
> Services bieten leider alle kein REST Interface, da wäre das einfacher:
>
>
> require "erb"
> require "net/http"
>
> class ServiceXYZ < ActiveRecord::Base
>
> def initialize(username, password, service_id)
> @USERNAME = username
> @PASSWORD = password
> @SERVICE = Service.find(service_id) # Hier finden sich die ganzen
> Daten des eigentlichen WebService, den ich ansprechen will
> @USERAGENT = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE;
> rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1'
> end
>
> # der Login läuft indem ich meisst erst ein GET absetze, dann Cookie
> setze und die Benutzerdaten danach POST'e
>
> def login
> @success = true
> unless @HEADERS.nil?
> logger.warn("You should already be logged in!")
> end
> @http = Net::HTTP.new(@SERVICE.domain, 80)
> resp, data = @http.get(@SERVICE.login_path_1, {'User-Agent' =>
> @USERAGENT})
> if resp.code == "200"
> @COOKIE = resp.response['set-cookie']
> data =
>
> "username=#{ERB::Util.url_encode(@USERNAME)}&password=#{ERB::Util.url_encode(@PASSWORD)}"
> @HEADERS = {
> 'Cookie' => @COOKIE,
> 'Referer' => 'http://'[EMAIL PROTECTED]@SERVICE.login_path_1,
> 'Content-Type' => 'application/x-www-form-urlencoded',
> 'User-Agent' => @USERAGENT
> }
> resp, data = @http.post(@SERVICE.login_path_1, data, @HEADERS)
> if resp.code == "302"
> @COOKIE = resp.response['set-cookie']
> @logged_in = false
> data.each_line do |line|
> @logged_in = true if line.match(/my\/archive/) # Text Check,
> der nur nach positivem Login ok ist
> end
> @success = false if not @logged_in
> else
> @success = false
> end
> else
> @success = false
> end
> return(@success)
> end
>
> # hier nun die eigentliche Schulball Veranstaltung
>
> def do_stuff_with(content_id)
> @success = false
> @content = Content.find(content_id)
> data = "item%5Bbla%5D=#{ERB::Util.url_encode(@content.bla)}&item%
> 5Bblu%5D=#{ERB::Util.url_encode(@content.blu)"
> @HEADERS = {
> 'Cookie' => @COOKIE,
> 'Content-Type' => 'application/x-www-form-urlencoded',
> 'User-Agent' => @USERAGENT
> }
> resp, data = @http.post(@SERVICE.save_path, data, @HEADERS)
> if resp.code == "200"
> data.each_line do |line|
> @success = true if line.match(/Your\sitem\shas\sbeen\ssaved/)
> end
> else
> @success = false
> end
> return(@success)
> end
>
> end
>
>
> Was ich nicht tue, ist ein explizites Close auf die Connection. Ich
> dachte auch nicht, dass das bei HTTP notwendig sei, vielleicht ein
> Fehler. Da man hier aber sieht, dass pro Aufruf der Action wirklich nur
> ein Object instanziert wird, kann dieses keine Mongrelinstanzen belegen.
> Vorallem weil es ja server side kreiert wird. ps zeigt ja auch keine
> weiteren Instanzen, wenn ich diese Action aufrufe.
>
> Bitte nicht spekulieren, was ich hier tue, es ist nicht, wonach es
> aussieht ;o)
> Und bitte keine bösen Worte, ich weiss, dass der Code 'ne Katastrophe
> ist, ist auch nur eine schnelle Idee, pragmatisch umgesetzt.
>
> Grüße
> Jan
>
>
> _______________________________________________
> rubyonrails-ug mailing list
> [email protected]
> http://mailman.headflash.com/mailman/listinfo/rubyonrails-ug
>
>
--
Jan Prill
Rechtsanwalt
Babendiekstraße 60 B
22587 Hamburg
Tel +49 (0)40 41265809 Fax +49 (0)40 380178-73022
Mobil +49 (0)171 3516667
_______________________________________________
rubyonrails-ug mailing list
[email protected]
http://mailman.headflash.com/mailman/listinfo/rubyonrails-ug