[Mongrel] mongrel thread safety and global variables

hemant gethemant at gmail.com
Fri Sep 1 10:02:53 EDT 2006


Will, mutex solve the problem?
I tried using them and seem to work.But as i said, the problem occurs very
less often.

There is another problem, if i use Mutex to synchronize, calls, then some
calls would take long and time and some would return immediately.so, a
request that takes long time, will block the other one.



On 9/1/06, hemant <gethemant at gmail.com> wrote:
>
> On 9/1/06, hemant <gethemant at gmail.com> wrote:
>
> >
> > In environment.rb file, I initialize a connection to some data vending
> > servers, through TCP sockets.
> >
> > The connection object is global and hence the code:
> >
> > #environment.rb
> > $generic_connection = ConnectionClass.instance (singleton class)
> > $generic_connection.connect( this call will make the connection)
> >
>
> The above approach is to make sure that, only one connection is made to
> the data vending servers.ConnectionClass is a library Class that, I have
> written to handle connections and to ensure exception handling and all that
> stuff.
>
> Now, in our rails code, whenever we need some data from these data vending
> servers, we use this global variable to get the data.
>
> #in controllers
> $generic_connection.get_data('<our internal protocol>')
>
>
>
> Since, we switched to mongrel, we are facing a strange issue. Our protocol
> code, specify what kind of data we want from data vending servers.So, lets
> say we want, x informatio, then we specify xxx as protocol code and get the
> data. protocol code "yyy" would give completely different kind of data.
> Now..sometimes what happens is, an Ajax call requests xxx protocol code and
> in the response we get data of protocol code yyy. Data vending servers are
> threaded again, and for each connection it starts a new thread and each
> request is served on a new thread.
> Data vending servers are again mostly written in ruby.
>
> Now, I am wondering where is the problem?
>
> As i know, mongrel serves requests on new threads, so what happens to this
> global variable that is shared among the threads.Is there a possiblity
> that, problem is here?
> I mean, lets say a thread is using this global variable for fetching data
> for protocol code xxx and same time another thread requests for protocol
> code yyy. My connection class, which is basically a proxy to these data
> vending servers, may not be thread safe.If this is the problem, then can
> anybody suggest better approach of making single connection to data vending
> servers, without using shared global variables.
>
>
>
> It could be a problem with our data vending servers also.But I am not so,
> sure about that.
>
>
> For anyone interested here is the ConnectionClass code:
>
> require 'socket'
> require 'timeout'
> require 'singleton'
> require 'yaml'
>
> class ConnectionClass
>   include Singleton
>
>   def connect
>     p = YAML.load(File.read("#{RAILS_ROOT}/config/parameters.yaml"))
>     @socket_file = p["socket_file"]
>     return connect_to_proxy
>   end
>
>
>   def connect_to_proxy
>     begin
>       @proxy_con = UNIXSocket.open(@socket_file.strip)
>       return @proxy_con
>     rescue Exception => e
>       return nil
>     end
>   end
>
>   def get_data(request_string)
>     req_array = request_string.split(':')
>     code = req_array[0].strip
>     msg = req_array[1].strip
>     symbol = req_array[2].strip
>
>     return get_data_from_proxy(code,symbol)
>
>   end
>
>
>   def get_data_from_proxy(code,symbol)
>     temp_string = code + '<' + symbol + '>'
>
>     ret_data = nil
>
>     begin
>       @proxy_con.puts(temp_string)
>     rescue Errno::EPIPE
>       unless connect_to_proxy.nil?
>         @proxy_con.puts(temp_string)
>       else
>         return nil
>       end
>     rescue Exception => e
>       return nil
>     end
>
>     begin
>       timeout(8) do
>         ret_data = @proxy_con.gets()
>       end
>     rescue Timeout::Error
>       return nil
>     rescue Exception => e
>       return nil
>     end
>
>
>     if ret_data =~ /^600*/
>       return nil
>     elsif ret_data =~ /^620*/
>       return nil
>     else
>       return ret_data
>     end
>   end
>
> end
>
> Evidently, when rails load(i.e mongrel starts), the only call made is,
> $generic_connection.connect(from environment.rb), and hence within this
> class, only @proxy_con should be shared among the threads IMHO.
> So, what happens when subsequent calls to $generic_connection.get_data is
> made from controller(ie mongrel threads)? while one thread is waiting for
> @proxy_con.gets, another thread can call the same method, but the question
> is, both the threads will share local variables defined within get_data and
> get_data_from_proxy methods?
>
> If i make, both the methods threaded, it should solve the problem? but i
> am wondering, how mongrel would handle it.
>



-- 
nothing much to talk
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/mongrel-users/attachments/20060901/274bbf9f/attachment.html 


More information about the Mongrel-users mailing list