I probably wasn't very clear about what's going on with Unicorn when I deploy a new version of the app. It's actually quite simple, and doesn't require loading new code on the fly. Here's what I do:
1) I update the app server code via: git pull (this doesn't affect the running processes due to Linux inode handling) 2) I send a signal to the Unicorn master process via: kill -USR2 <pid> 3) Unicorn then instructs each of the worker processes to quit after finishing their current request, if any. 4) When each worker process quits, Unicorn automatically spins up a new one that happens to use the new code Requests continue to be handled by existing worker processes, so there's no downtime. I'm not too concerned about this aspect - I could easily instrument this manually by making the worker processes accept a signal/message/etc. that would instruct them to quit after the current request. The monit solution seems fine, but it typically works via a pid file, so I'd simply have to ensure that the N Racket server processes write their respective pid's to N separate files. It's not a big deal, but having something like Unicorn handle that is handy. I could probably just have monit pass a unique argument to each of the N processes e.g. 1, 2, 3, ... , N and store the pid's in pid1, pid2, ... , pidN. They could also use the arg to form the port they listen on 4311, 4312, ... , 431N I'm probably going to be dealing with only 2 or 4 cores typically, so the final solution doesn't need to be all that complicated. I appreciate all the info folks have supplied, and I learned something new from George about multiple apps listening on the same port - I assume that involves SO_REUSE - I may have to research that. Having the OS handle the scheduling may be worth considering. On Saturday, November 24, 2018 at 2:21:11 PM UTC-5, Jesse Alama wrote: > > Hi Brian, > > On 23 Nov 2018, at 21:46, Brian Adkins wrote: > > > I'm porting a web application from Ruby/Rails to Racket, and I'd like > > something to manage the Racket server processes. > > > > In the Ruby world, I'm currently using Unicorn ( > > https://en.wikipedia.org/wiki/Unicorn_(web_server) ) prior to that I > > used > > Nginx Passenger ( https://en.wikipedia.org/wiki/Phusion_Passenger ), > > etc. > > Another popular Ruby app server is Puma > > ( https://en.wikipedia.org/wiki/Puma_(web_server) ) > > > > I'll use nginx as the front end web server, and it will proxy to the > > application server. In a nutshell, for Unicorn, I configure the > > location of > > the Rails app, configure how many processes I want, and Unicorn will > > spin > > up that number of Rails processes and handle routing requests from > > nginx to > > each of the Rails processes in some fashion. If a Rails process exists > > abnormally, it will spin up another one to replace it. To deploy a new > > version of my app, I can send a signal to the Unicorn master process > > to > > *gracefully* restart all the processes i.e. it waits for the current > > request to finish, and then kills the process and spins up a new one > > using > > the new version of the app. > > > > Are there similar application servers available for Racket? > > Alternatively, > > if not, and you have long running applications in Racket, what are you > > using to manage them? > > Just to echo the experience of others here: I've also used the Racket > server straight up on the unfiltered Internet, and had no problems > except (as Greg mentioned) weird requests flowing in that the server > found dubious. Without crashing, I should add; these weird (if not > downright malformed) requests didn't kill the web server, they just > created a lot of junk in the logs. Putting Racket behind a server that's > more prepared to handle such junk (e.g., OpenBSD's httpd) restores log > sanity. > > To get back to your real question, though: you want to know how to > deploy a new version of a running web app. > > (1) There's the reloadable package > > https://pkgs.racket-lang.org/package/reloadable > > I myself haven't used it, but it's definitely relevant. That looks like > a real Racket-y solution, which is what I think you're looking for. > > (2) I myself view these issues as DevOps-y things to be dealt with not > so much in Racket and more at the OS/service level. Generating an > httpd.conf file and then using OpenBSD's rcctl to switch out the old > config for the new one has been fine for me. This is perhaps a deviant > view; the reloadable package probably reflects a more catholic > understanding of the situation. But there may be cases where you change > your code in ways that are just too big, and I bet you'll find yourself > needing to do something like what I do and what you're currently doing > with Unicorn. > > Jesse > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.

