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

Antwort per Email an