Skip to content

Invoking an existing lambda will trigger an error on 'start_server!' #18

Closed

Description

@brcarp

The suggested configuration here:

config.to_prepare { LambdaPunch.start_server! }

... will cause an Errno::EADDRINUSE error to be raised if a lambda is invoked manually, because the LambdaPunch server will have already been started. A call to aws lambda invoke for example yields the following error and stack trace:

Address already in use - bind(2) for "127.0.0.1" port 9030
	/usr/local/lib/ruby/2.7.0/drb/drb.rb:883:in 'initialize':
	    Address already in use - bind(2) for "127.0.0.1" port 9030 (Errno::EADDRINUSE)
	from /usr/local/lib/ruby/2.7.0/drb/drb.rb:883:in 'open'
	from /usr/local/lib/ruby/2.7.0/drb/drb.rb:883:in 'open_server'
	from /usr/local/lib/ruby/2.7.0/drb/drb.rb:766:in 'block in open_server'
	from /usr/local/lib/ruby/2.7.0/drb/drb.rb:764:in 'each'
	from /usr/local/lib/ruby/2.7.0/drb/drb.rb:764:in 'open_server'
	from /usr/local/lib/ruby/2.7.0/drb/drb.rb:1466:in 'initialize'
	from /usr/local/lib/ruby/2.7.0/drb/drb.rb:1772:in 'new'
	from /usr/local/lib/ruby/2.7.0/drb/drb.rb:1772:in 'start_service'
	from /app/vendor/bundle/ruby/2.7.0/gems/lambda_punch-1.0.3/lib/lambda_punch/server.rb:22:in 'initialize'
	from /usr/local/lib/ruby/2.7.0/singleton.rb:125:in 'new'
	from /usr/local/lib/ruby/2.7.0/singleton.rb:125:in 'block in instance'
	from /usr/local/lib/ruby/2.7.0/singleton.rb:123:in 'synchronize'
	from /usr/local/lib/ruby/2.7.0/singleton.rb:123:in 'instance'
	from /app/vendor/bundle/ruby/2.7.0/gems/lambda_punch-1.0.3/lib/lambda_punch/server.rb:15:in 'start!'
	from /app/vendor/bundle/ruby/2.7.0/gems/lambda_punch-1.0.3/lib/lambda_punch.rb:36:in 'start_server!'
	from /app/config/environments/production.rb:141:in 'block (2 levels) in <main>'

I was able to work around this doing something like the following:

  config.to_prepare do
    LambdaPunch.start_server!
  rescue Errno::EADDRINUSE => e
    Rails.logger.info("LambdaPunch is already running! (#{e.class})")
  end

Is there a better way to do this, or is there something that LambdaPunch can support natively to check to see if a server is already running, e.g. an alive? predicate similar to what's in DRb?

Activity

  1. brcarp commented on Jun 9, 2023

    @brcarp
    Author

    💭 Another idea i had was to investigate ARGV and maybe skip the start_server! call if Rails was executed with runner?

    Unfortunately RunnerCommand does ARGV.replace(command_argv) which basically removes runner from ARGV. 😞

  2. brcarp commented on Jun 9, 2023

    @brcarp
    Author

    💭 Another idea i had was to investigate ARGV and maybe skip the start_server! call if Rails was executed with runner?

    Unfortunately RunnerCommand does ARGV.replace(command_argv) which basically removes runner from ARGV. 😞

    Ooh, what if I add if Rails.const_defined?(:Server)? That might be sufficient to distinguish rails server from rails runner.

  3. metaskills commented on Jun 12, 2023

    @metaskills
    Member

    Oh, I see the problem. Invoking is not the issue, technically there is no double init process for Lambda. What is happening is that when you are invoking, you are starting another Rails process off on the same function. Never anticipated that. I think ideally you could talk to the existing process. Not only would the that mean the "runner" action(s) and even "tasks" would be faster... but it would mean you can rely on LambdaPunch just working inside those tasks without coordination. How do you feel about the following.

    We make a small change to Lamby's cmd handler (https://github.com/rails-lambda/lamby/blob/master/lib/lamby/handler.rb#L84-L103) to have one more... the last thing we will ever need... a basic method executor interface.

    {
      "lamby": {
        "cmd": {
          "method": "SomeConstant.method",
          "args": ["..."]
        }
      }
    }

    So the idea here would be that anything would work here. We can use this vs the runner. Builders can add syntactic sugar to this. For example, want to call a migration? There are top level methods to do that. We could even build a virtual REPL on this if the interface detected an array of commands. Thoughts? See where I am headed?

  4. brcarp commented on Jun 12, 2023

    @brcarp
    Author

    Ooh, what if I add if Rails.const_defined?(:Server)? That might be sufficient to distinguish rails server from rails runner.

    For the record, this does NOT work. These Rails lambdas are not running "rails server", which I might have realized if I thought about it for two seconds.

  5. metaskills commented on Jun 14, 2023

    @metaskills
    Member

    @brcarp Would you like to make a PR to LambdaPunch that does the Errno::EADDRINUSE in the gem? That sounds like the best way forward?

  6. metaskills commented on Jun 9, 2024

    @metaskills
    Member

    Added this in v1.1.4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions