unicorn Ruby/Rack server user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
* About Unicorn Rack handler
@ 2009-11-04 12:37 Lin Jen-Shin (aka godfat 真常)
  2009-11-04 17:07 ` Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Lin Jen-Shin (aka godfat 真常) @ 2009-11-04 12:37 UTC (permalink / raw)
  To: mongrel-unicorn; +Cc: godfat 真常

Hi,

A couple days ago, I was trying to run Unicorn for Ramaze,
and found that `Unicorn.run' didn't share the same interface
with other Rack handlers, i.e. `options[:Host]' and `options[:Port]'

Because of this, I can't just use:

  Rack::Handler.register('unicorn', 'Unicorn')

And invoke this:

  Ramaze.start(:adapter => 'unicorn', :port => 8080)

To address this, I added a simple wrapper in
Innate (which is the core of Ramaze):

http://github.com/godfat/innate/commit/9d607f41fdeeca366a9a07155e685ae2605c7025

In short, simply hack the config to:

  {:listeners => ["#{config[:Host]}:#{config[:Port]}"]}

Should we adapt to this interface in Unicorn::Configurator,
or provide an additional Rack handle to adapt to this,
or maintain this Rack handler in Rack repository, just like the others?
http://github.com/rack/rack/tree/master/lib/rack/handler

I'm looking forward to your opinion, many thanks!
cheers,

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: About Unicorn Rack handler
  2009-11-04 12:37 About Unicorn Rack handler Lin Jen-Shin (aka godfat 真常)
@ 2009-11-04 17:07 ` Eric Wong
  2009-11-05  4:43   ` Lin Jen-Shin (aka godfat 真常)
  0 siblings, 1 reply; 8+ messages in thread
From: Eric Wong @ 2009-11-04 17:07 UTC (permalink / raw)
  To: unicorn list; +Cc: godfat 真常

"Lin Jen-Shin (aka godfat 真常)" <godfat@godfat.org> wrote:
> Hi,
> 
> A couple days ago, I was trying to run Unicorn for Ramaze,
> and found that `Unicorn.run' didn't share the same interface
> with other Rack handlers, i.e. `options[:Host]' and `options[:Port]'
> 
> Because of this, I can't just use:
> 
>   Rack::Handler.register('unicorn', 'Unicorn')
> 
> And invoke this:
> 
>   Ramaze.start(:adapter => 'unicorn', :port => 8080)
> 
> To address this, I added a simple wrapper in
> Innate (which is the core of Ramaze):
> 
> http://github.com/godfat/innate/commit/9d607f41fdeeca366a9a07155e685ae2605c7025
> 
> In short, simply hack the config to:
> 
>   {:listeners => ["#{config[:Host]}:#{config[:Port]}"]}
> 
> Should we adapt to this interface in Unicorn::Configurator,
> or provide an additional Rack handle to adapt to this,
> or maintain this Rack handler in Rack repository, just like the others?
> http://github.com/rack/rack/tree/master/lib/rack/handler

I think making Unicorn.run add to :listeners if :Host or :Port are set
will work.  I'm not sure if launching Unicorn directly from `rackup' can
ever work right without being too intrusive to the other servers, so
having a Unicorn Rack handler in distributed with Rack would't make
sense.   Unicorn needs to capture ARGV (before option parsing) and parse
its own config file, neither of which is doable out-of-the-box with
rackup.

Does something like this work? (not tested).

diff --git a/lib/unicorn.rb b/lib/unicorn.rb
index 0f2b597..d4a00e0 100644
--- a/lib/unicorn.rb
+++ b/lib/unicorn.rb
@@ -17,6 +17,14 @@ module Unicorn
 
   class << self
     def run(app, options = {})
+      # compatibility with other interfaces (Ramaze)
+      host = options.delete(:Host)
+      port = options.delete(:Port)
+      if host || port
+        port ||= Const::DEFAULT_PORT
+        host ||= Const::DEFAULT_HOST
+        (options[:listeners] ||= []) << "#{host}:#{port}"
+      end
       HttpServer.new(app, options).start.join
     end
   end

On the other hand, does Innate make it possible to do transparent
upgrades (since rackup does not)?  I'll look into it a bit more later...

-- 
Eric Wong
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: About Unicorn Rack handler
  2009-11-04 17:07 ` Eric Wong
@ 2009-11-05  4:43   ` Lin Jen-Shin (aka godfat 真常)
  2009-11-05  4:47     ` Lin Jen-Shin (aka godfat 真常)
  2009-11-05  7:28     ` Eric Wong
  0 siblings, 2 replies; 8+ messages in thread
From: Lin Jen-Shin (aka godfat 真常) @ 2009-11-05  4:43 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

On Thu, Nov 5, 2009 at 1:07 AM, Eric Wong <normalperson@yhbt.net> wrote:
> I think making Unicorn.run add to :listeners if :Host or :Port are set
> will work.  I'm not sure if launching Unicorn directly from `rackup' can
> ever work right without being too intrusive to the other servers, so
> having a Unicorn Rack handler in distributed with Rack would't make
> sense.   Unicorn needs to capture ARGV (before option parsing) and parse
> its own config file, neither of which is doable out-of-the-box with
> rackup.

I see. On the other hand, it would be great if `rackup' could work with
Unicorn directly. Perhaps something like:

  rackup -r config/unicorn.rb -s unicorn -p 12345 config.ru

This would require unicorn config to change to something like:

  Unicorn::Configurator.instance.instance_eval{
    # original config content
  }

Then `Unicorn.run' should check if Configurator
singleton has been configured, and use it instead.

I would want this because I have a rackup cluster script.
If this would work, then I don't have to change the existing
script to adapt to Unicorn with a -c option, along with
changing `rackup' to `unicorn'.

Here's the script:
http://github.com/godfat/app-deploy/blob/master/lib/app-deploy/rack_cluster.rb

Here's an example config for `rack_cluster':
http://github.com/godfat/app-deploy/blob/master/example/rack_cluster.yaml

I know I won't need rack "cluster" once I switch to Unicorn.
Perhaps what I should do is just drop rack cluster support,
then many things could be simplified.

> Does something like this work? (not tested).
>
> diff --git a/lib/unicorn.rb b/lib/unicorn.rb
> index 0f2b597..d4a00e0 100644
> --- a/lib/unicorn.rb
> +++ b/lib/unicorn.rb
> @@ -17,6 +17,14 @@ module Unicorn
>
>   class << self
>     def run(app, options = {})
> +      # compatibility with other interfaces (Ramaze)
> +      host = options.delete(:Host)
> +      port = options.delete(:Port)
> +      if host || port
> +        port ||= Const::DEFAULT_PORT
> +        host ||= Const::DEFAULT_HOST
> +        (options[:listeners] ||= []) << "#{host}:#{port}"
> +      end
>       HttpServer.new(app, options).start.join
>     end
>   end

Yes, work fine at first try. Many thanks for your work!
The working `start.rb' for Ramaze is:

  require 'unicorn'
  Rack::Handler.register('unicorn', 'Unicorn')
  Ramaze.start(:adapter => 'unicorn', :port => 7000)

> On the other hand, does Innate make it possible to do transparent
> upgrades (since rackup does not)?  I'll look into it a bit more later...

I am not sure what do you mean transparent here,
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: About Unicorn Rack handler
  2009-11-05  4:43   ` Lin Jen-Shin (aka godfat 真常)
@ 2009-11-05  4:47     ` Lin Jen-Shin (aka godfat 真常)
  2009-11-05  7:29       ` Eric Wong
  2009-11-05  7:28     ` Eric Wong
  1 sibling, 1 reply; 8+ messages in thread
From: Lin Jen-Shin (aka godfat 真常) @ 2009-11-05  4:47 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

2009/11/5 Lin Jen-Shin (aka godfat 真常) <godfat@godfat.org>:
> On Thu, Nov 5, 2009 at 1:07 AM, Eric Wong <normalperson@yhbt.net> wrote:
>> On the other hand, does Innate make it possible to do transparent
>> upgrades (since rackup does not)?  I'll look into it a bit more later...
>
> I am not sure what do you mean transparent here,

Oops, accidentally sent incomplete mail, sorry.

I am not sure what do you mean transparent here,
but I would guess Innate work better than rackup. :p

cheers,
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: About Unicorn Rack handler
  2009-11-05  4:43   ` Lin Jen-Shin (aka godfat 真常)
  2009-11-05  4:47     ` Lin Jen-Shin (aka godfat 真常)
@ 2009-11-05  7:28     ` Eric Wong
  2009-11-05 15:13       ` Lin Jen-Shin (aka godfat 真常)
  1 sibling, 1 reply; 8+ messages in thread
From: Eric Wong @ 2009-11-05  7:28 UTC (permalink / raw)
  To: Lin Jen-Shin (aka godfat 真常); +Cc: unicorn list

"Lin Jen-Shin (aka godfat 真常)" <godfat@godfat.org> wrote:
> On Thu, Nov 5, 2009 at 1:07 AM, Eric Wong <normalperson@yhbt.net> wrote:
> > I think making Unicorn.run add to :listeners if :Host or :Port are set
> > will work.  I'm not sure if launching Unicorn directly from `rackup' can
> > ever work right without being too intrusive to the other servers, so
> > having a Unicorn Rack handler in distributed with Rack would't make
> > sense.   Unicorn needs to capture ARGV (before option parsing) and parse
> > its own config file, neither of which is doable out-of-the-box with
> > rackup.
> 
> I see. On the other hand, it would be great if `rackup' could work with
> Unicorn directly. Perhaps something like:
> 
>   rackup -r config/unicorn.rb -s unicorn -p 12345 config.ru

As I explained in the other email, this unfortunately can't ever give
you all the features that Unicorn has.

I've made an effort to keep everything else as compatible and the
migration paths as easy as possible.

> I would want this because I have a rackup cluster script.
> If this would work, then I don't have to change the existing
> script to adapt to Unicorn with a -c option, along with
> changing `rackup' to `unicorn'.
> 
> Here's the script:
> http://github.com/godfat/app-deploy/blob/master/lib/app-deploy/rack_cluster.rb
> 
> Here's an example config for `rack_cluster':
> http://github.com/godfat/app-deploy/blob/master/example/rack_cluster.yaml
> 
> I know I won't need rack "cluster" once I switch to Unicorn.
> Perhaps what I should do is just drop rack cluster support,
> then many things could be simplified.

Yeah, it's probably simpler to just use "unicorn" than to wrap it.

It's really hard use the process management functionality in a libified
form since we rely on things like $0 and ARGV.  On the other hand, since
Unicorn is designed to work with nginx, you can use the same
scripts/signals for managing both.

> > Does something like this work? (not tested).
> >
> > diff --git a/lib/unicorn.rb b/lib/unicorn.rb
> > index 0f2b597..d4a00e0 100644
> > --- a/lib/unicorn.rb
> > +++ b/lib/unicorn.rb
> > @@ -17,6 +17,14 @@ module Unicorn
> >
> >   class << self
> >     def run(app, options = {})
> > +      # compatibility with other interfaces (Ramaze)
> > +      host = options.delete(:Host)
> > +      port = options.delete(:Port)
> > +      if host || port
> > +        port ||= Const::DEFAULT_PORT
> > +        host ||= Const::DEFAULT_HOST
> > +        (options[:listeners] ||= []) << "#{host}:#{port}"
> > +      end
> >       HttpServer.new(app, options).start.join
> >     end
> >   end
> 
> Yes, work fine at first try. Many thanks for your work!
> The working `start.rb' for Ramaze is:
> 
>   require 'unicorn'
>   Rack::Handler.register('unicorn', 'Unicorn')
>   Ramaze.start(:adapter => 'unicorn', :port => 7000)
> 
> > On the other hand, does Innate make it possible to do transparent
> > upgrades (since rackup does not)?  I'll look into it a bit more later...
> 
> I am not sure what do you mean transparent here,

Can you try and see if the USR2 handling of Unicorn allows
a transparent upgrade here?  If it doesn't then I don't think
it's worth supporting an interface that's crippled compared
to using the plain `unicorn' command.

-- 
Eric Wong
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: About Unicorn Rack handler
  2009-11-05  4:47     ` Lin Jen-Shin (aka godfat 真常)
@ 2009-11-05  7:29       ` Eric Wong
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Wong @ 2009-11-05  7:29 UTC (permalink / raw)
  To: Lin Jen-Shin (aka godfat 真常); +Cc: unicorn list

"Lin Jen-Shin (aka godfat 真常)" <godfat@godfat.org> wrote:
> 2009/11/5 Lin Jen-Shin (aka godfat 真常) <godfat@godfat.org>:
> > On Thu, Nov 5, 2009 at 1:07 AM, Eric Wong <normalperson@yhbt.net> wrote:
> >> On the other hand, does Innate make it possible to do transparent
> >> upgrades (since rackup does not)?  I'll look into it a bit more later...
> >
> > I am not sure what do you mean transparent here,
> 
> Oops, accidentally sent incomplete mail, sorry.
> 
> I am not sure what do you mean transparent here,
> but I would guess Innate work better than rackup. :p

Transparent, zero-downtime upgrades (USR2 + QUIT) that Unicorn
can do like nginx[1].

The issue here with rackup is that it changes ARGV with the option
parser before Unicorn can get to it.  So when Unicorn receives the USR2
signal and respawns itself, it won't be able to spawn a child with the
same command-line options as its parent.  Using the "unicorn" script
will allow it to always save its ARGV before OptionParser has a chance
to mangle it.

[1] - http://unicorn.bogomips.org/SIGNALS.html
-- 
Eric Wong
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: About Unicorn Rack handler
  2009-11-05  7:28     ` Eric Wong
@ 2009-11-05 15:13       ` Lin Jen-Shin (aka godfat 真常)
  2009-11-05 23:19         ` Eric Wong
  0 siblings, 1 reply; 8+ messages in thread
From: Lin Jen-Shin (aka godfat 真常) @ 2009-11-05 15:13 UTC (permalink / raw)
  To: Eric Wong; +Cc: unicorn list

2009/11/5 Eric Wong <normalperson@yhbt.net>:
> As I explained in the other email, this unfortunately can't ever give
> you all the features that Unicorn has.
>
> I've made an effort to keep everything else as compatible and the
> migration paths as easy as possible.

Many, many thanks for your effort on Unicorn.
It's awesome, in all ways. I would switch all services
at my working place to Unicorn at some point.

> Can you try and see if the USR2 handling of Unicorn allows
> a transparent upgrade here?  If it doesn't then I don't think
> it's worth supporting an interface that's crippled compared
> to using the plain `unicorn' command.

I think it does work. This is start.rb:

###
#!/usr/bin/env ruby
require File.expand_path('app', File.dirname(__FILE__))
require 'unicorn'
Rack::Handler.register('unicorn', 'Unicorn')
Ramaze.start(:adapter => 'unicorn', :port => 7000)
###

It won't work if I invoke start.rb like this:
$ ruby start.rb
(perhaps it's impossible to get the `ruby' ?)
but it does work if I invoke this way:
$ ./start.rb
(tested with different debug output in lib/unicorn.rb)

On the other hand, `ramaze' command won't work,
and I guess it's because it uses `rackup', which
you've explained why it won't.

I am wondering.. Could `rackup' be fixed for this?
For instance, use the same way as `unicorn' in `rackup'?
If so, I would be glad to try to fix that in rackup.
I would try it later in my free time.

cheers,
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: About Unicorn Rack handler
  2009-11-05 15:13       ` Lin Jen-Shin (aka godfat 真常)
@ 2009-11-05 23:19         ` Eric Wong
  0 siblings, 0 replies; 8+ messages in thread
From: Eric Wong @ 2009-11-05 23:19 UTC (permalink / raw)
  To: Lin Jen-Shin (aka godfat 真常); +Cc: unicorn list

"Lin Jen-Shin (aka godfat 真常)" <godfat@godfat.org> wrote:
> 2009/11/5 Eric Wong <normalperson@yhbt.net>:
> > As I explained in the other email, this unfortunately can't ever give
> > you all the features that Unicorn has.
> >
> > I've made an effort to keep everything else as compatible and the
> > migration paths as easy as possible.
> 
> Many, many thanks for your effort on Unicorn.
> It's awesome, in all ways. I would switch all services
> at my working place to Unicorn at some point.

Cool, good to know :)

> > Can you try and see if the USR2 handling of Unicorn allows
> > a transparent upgrade here?  If it doesn't then I don't think
> > it's worth supporting an interface that's crippled compared
> > to using the plain `unicorn' command.
> 
> I think it does work. This is start.rb:
> 
> ###
> #!/usr/bin/env ruby
> require File.expand_path('app', File.dirname(__FILE__))
> require 'unicorn'
> Rack::Handler.register('unicorn', 'Unicorn')
> Ramaze.start(:adapter => 'unicorn', :port => 7000)
> ###
> 
> It won't work if I invoke start.rb like this:
> $ ruby start.rb
> (perhaps it's impossible to get the `ruby' ?)
> but it does work if I invoke this way:
> $ ./start.rb
> (tested with different debug output in lib/unicorn.rb)

Yeah, running "ruby start.rb" throws off $0 unless start.rb is in $PATH.
"ruby ./start.rb" should work, too, but it's ugly.  I think there
are/were cases where "#!/usr/bin/env ruby" won't even work as a shebang,
too.

> On the other hand, `ramaze' command won't work,
> and I guess it's because it uses `rackup', which
> you've explained why it won't.
> 
> I am wondering.. Could `rackup' be fixed for this?
> For instance, use the same way as `unicorn' in `rackup'?
> If so, I would be glad to try to fix that in rackup.
> I would try it later in my free time.

It would require `rackup' to do a "require 'unicorn'" before it does any
option parsing.  That would be unnecessarily intrusive if one has
Unicorn installed but wants to test with a different server.

-- 
Eric Wong
_______________________________________________
mongrel-unicorn mailing list
mongrel-unicorn@rubyforge.org
http://rubyforge.org/mailman/listinfo/mongrel-unicorn

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2009-11-05 23:26 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-04 12:37 About Unicorn Rack handler Lin Jen-Shin (aka godfat 真常)
2009-11-04 17:07 ` Eric Wong
2009-11-05  4:43   ` Lin Jen-Shin (aka godfat 真常)
2009-11-05  4:47     ` Lin Jen-Shin (aka godfat 真常)
2009-11-05  7:29       ` Eric Wong
2009-11-05  7:28     ` Eric Wong
2009-11-05 15:13       ` Lin Jen-Shin (aka godfat 真常)
2009-11-05 23:19         ` Eric Wong

Code repositories for project(s) associated with this public inbox

	https://yhbt.net/unicorn.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).