igrigorik / em-http-request

Asynchronous HTTP Client (EventMachine + Ruby)
1.22k stars 220 forks source link

Doubt about memory leaks #350

Open Marcos-Amazonas opened 3 years ago

Marcos-Amazonas commented 3 years ago

Hi, my name is Marcos and I'm have a doubt about the EventMachine.run loop, sorry if this question is a little stupid.

Considering the code below

EventMachine.run {
      http = EventMachine::HttpRequest.new('http://google.com/').get :query => {'keyname' => 'value'}

      http.errback { p 'Uh oh'; EM.stop }
      http.callback {
        p http.response_header.status
        p http.response_header
        p http.response

        EventMachine.stop  # -> This line right here
      }
    }

First question If I do not call the EventMachine.stop command at the end of the http.callback block will I have a memory leak?

Seccond question If I open two EventMachine.run loops am I using the same loop or different loops? Will I have a memory leak if I dont use the EventMachine.stop command after the requests http requests have responded or I can simply use the calls like the bellow example without the EventMachine.stop** command like the code below.

EventMachine.run {
      http = EventMachine::HttpRequest.new('http://google.com/').get :query => {'keyname' => 'value'}

      http.errback { p 'Uh oh'; EM.stop }
      http.callback {
        # Do something
      }
    }

Thanks in advance

jpcamara commented 3 years ago

Hi Marcos! I'm not related to this project, but I think I can answer your question sufficiently. This isn't really a question related to em-http-request, so i'll reference the EventMachine documentation.

First question answer

If I do not call the EventMachine.stop command at the end of the http.callback block will I have a memory leak?

Kind of. The reactor will run forever if you don't call stop. So you could consider that to be a "leak". But also - if you run it on the current thread - until you call stop you can't run any other code. So if you want to use it in the current thread and be able to run other code afterwards, you have to call stop.

In their wiki documentation here, they mention that the reactor will loop infinitely, until stop is called: https://github.com/eventmachine/eventmachine/wiki/General-Introduction#the-reactor

Second question answer

If I open two EventMachine.run loops am I using the same loop or different loops?

Based on their source code and documentation, calling EventMachine.run will always be the same loop (unless you fork and are in a completely different process). So if you expect to call it multiple times, it may be better to not call stop.

There is only one EventMachine "reactor" per process (the "reactor" is the event loop that starts when you call EventMachine.run).

In the run source code, it checks if the reactor is already running here: https://github.com/eventmachine/eventmachine/blob/b50c135dfdd4e7b20c8e0b7ce1d8fe7176d4d14d/lib/eventmachine.rb#L171 This checks if the run method was called, and if we're still in the same process. So per process, across all threads, you have one reactor.