Re: [racket-users] Racket application servers

2018-11-23 Thread Philip McGrath
I'm not sure if this was clear from what I said earlier, but I use the
Racket web server without anything in front of it. In fact, Racket does SSL
termination and serves as a proxy for non-Racket services. We have been
completely satisfied with its performance and reliability.

-Philip


On Sat, Nov 24, 2018 at 12:03 AM Greg Hendershott 
wrote:

> In my experience a Racket web server will just stubbornly continue to
> work for months at a time, if you let it.
>
> (Reminds me of the aviation joke. In the future, cockpits will have
> just one human pilot and a dog. The dog is there to bite the human if
> they try to turn off the autopilot.)
>
> I have a site on one little t2.micro at AWS.
>
> It is behind an AWS application load balancer -- but mainly just as an
> easy way to do SSL termination.
>
> I also added WAF to filter script kiddies who don't bother to supply a
> valid Host header while they try to log into phpadmin or whatever. For
> non-FANG sites honestly that will be a large proportion of your
> traffic in terms of number of requests. It wasn't making the Racket
> web server sweat, I just wanted to noise out of my logs and stats.
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Racket application servers

2018-11-23 Thread Greg Hendershott
In my experience a Racket web server will just stubbornly continue to
work for months at a time, if you let it.

(Reminds me of the aviation joke. In the future, cockpits will have
just one human pilot and a dog. The dog is there to bite the human if
they try to turn off the autopilot.)

I have a site on one little t2.micro at AWS.

It is behind an AWS application load balancer -- but mainly just as an
easy way to do SSL termination.

I also added WAF to filter script kiddies who don't bother to supply a
valid Host header while they try to log into phpadmin or whatever. For
non-FANG sites honestly that will be a large proportion of your
traffic in terms of number of requests. It wasn't making the Racket
web server sweat, I just wanted to noise out of my logs and stats.

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Destructuring a list in (for ...)

2018-11-23 Thread Philip McGrath
Depends on what `x` is, both symbolically and in terms of binding:

(for/first ([(list _) #hash([(a) . 1])])
  list)

(define-match-expander x
  (syntax-rules ()
[(_ pat) (list pat)]))

(match '(ok)
  [(x v)
   v])

-Philip


On Fri, Nov 23, 2018 at 11:41 PM Greg Hendershott 
wrote:

> > The trouble, sadly, is that this grammar is ambiguous. In
> >
> >   (for ([(x y) s])
> > )
> >
> > should (x y) be parsed as a single match pattern or as two binders for a
> two-valued sequence (such as one produced by in-hash, for example)?
>
> Unless I'm being dense, (x y) isn't a valid single match pattern?
>
> [Quasipatterns like `(x y) or `(,x ,y) would be.]
>
> But even if it is grammatically possible, like I said at the end, I'm
> not sure it's worthwhile.
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Destructuring a list in (for ...)

2018-11-23 Thread Greg Hendershott
> The trouble, sadly, is that this grammar is ambiguous. In
>
>   (for ([(x y) s])
> )
>
> should (x y) be parsed as a single match pattern or as two binders for a 
> two-valued sequence (such as one produced by in-hash, for example)?

Unless I'm being dense, (x y) isn't a valid single match pattern?

[Quasipatterns like `(x y) or `(,x ,y) would be.]

But even if it is grammatically possible, like I said at the end, I'm
not sure it's worthwhile.

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Racket application servers

2018-11-23 Thread George Neuner



On 11/23/2018 4:38 PM, Philip McGrath wrote:

I'm not familiar with Ruby, so this is just some general information.

The Racket web server already supports concurrency with its built-in 
green threads, so handling one request won't block the concurrent 
handling of another. (Not all languages' built-in web servers do this; 
I don't know about Ruby in particular).


There isn't built-in support for parallelism, i.e. for taking 
advantage of multiple processor cores. This isn't built in, and I 
don't personally need this (my server only has two cores, and it runs 
a database and other processes in addition to Racket). However, it is 
probably possible to recreate the architecture you describe.


Essentially you would be running multiple instances of your 
application behind a load-balancer. If you want to use nginx as a load 
balancer, that's out of the equation; implementing a load-balancer in 
Racket would certainly be possible but probably more work. 
Extra-linguistically, you could just create a few systemd services or 
similar to run several totally separate Racket instances. Within 
Racket, you would want to build on "places." You can have N worker 
places running N instances of your application on N OS-level threads, 
plus a master place to control them. A mechanism for gracefully 
stopping the Racket web server is built in (see serve/launch/wait 
). 
Reloading isn't built in, but I've heard good things about the 
"reloadable" package 
(https://pkgs.racket-lang.org/package/reloadable), which should let 
you implement it if needed.


While I only run one instance of our application, I do use places to 
redirect HTTP to HTTPS.


One caveat is that all of this assumes that, if you are using 
continuations at all, you are using serializable continuations with 
`#lang web-server`. Making places work well with native continuations 
would probably be a lot of work, and it would probably be better to 
build that functionality into the Racket web server than to try to 
fake it as a client.


-Philip



Just a comment:

Multiple (identical) server instances running on the same machine can 
listen for connections on the same network port - an incoming client 
call will be connected to only one of them.  You only need to use 
different ports when services are not interchangeable [i.e. it matters 
which one you are talking to].


Process parallelism, in effect, can give you automatic connection load 
balancing on a single machine.  Using a separate load balancer in front 
technically is overkill for such situations, but it is a good design if 
you want to preserve the option to relocate your services to different 
machines.


George

--
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Destructuring a list in (for ...)

2018-11-23 Thread Philip McGrath
I actually have an experimental `in-match` macro, analogous to `in-value`:
https://docs.racket-lang.org/adjutor/Experimental.html#(form._((lib._adjutor%2Fmain..rkt)._in-match))

One open question with my version (and one of the reasons I consider this
experimental) is what should be done if one of the identifiers isn't bound
by the match pattern (or is bound by some but not all of the patterns) but
shadows another binding. Right now the binding from context is used, which
is nice in some cases but would probably be confusing in others. It might
be better to make that a syntax error.

-Philip


On Fri, Nov 23, 2018 at 1:29 PM Laurent  wrote:

> Maybe you could have something like (in-match ...) ?
>
> On Fri, Nov 23, 2018 at 4:54 PM Alexis King  wrote:
>
>> The trouble, sadly, is that this grammar is ambiguous. In
>>
>>   (for ([(x y) s])
>> )
>>
>> should (x y) be parsed as a single match pattern or as two binders for a
>> two-valued sequence (such as one produced by in-hash, for example)? You
>> could make it unambiguous in various ways, such as by requiring uses of
>> match patterns to all use the multi-valued binder syntax (with an extra set
>> of parens), but that’s a bit clumsy. Unfortunately, I can’t think of any
>> particularly elegant way to support match patterns in for loop binders in a
>> backwards-compatible way.
>>
>> Alexis
>>
>> > On Nov 22, 2018, at 20:14, Greg Hendershott 
>> wrote:
>> >
>> >> (define-syntax (match-for stx)
>> >
>> > That's nice.
>> >
>> > Sometimes I wish I could do the general thing -- use `match` patterns
>> > in the binding clauses for any `for`-family form.
>> >
>> > I often do something like this:
>> >
>> >(define xs (list (cons 1 2) (cons 3 4)))
>> >
>> >(for ([x (in-list xs)])
>> >  (match-define (cons a b) x)
>> >  (use a b))
>> >
>> > Instead it would be nice to write:
>> >
>> >(for ([(match-define (cons a b)) (in-list xs)])
>> >  (use a b))
>> >
>> > Or even just:
>> >
>> >(for ([(cons a b c) (in-list xs)])
>> >  (use a b))
>> >
>> > In the grammar, `id` becomes `id-or-match-pattern`.
>> >
>> > On the other hand, this would only really help in simple
>> > `match-define` destructuring -- as opposed to using `match` to handle
>> > variations in the data. And although I do the former a lot, I do the
>> > latter even more.
>>
>> --
>> 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 racket-users+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Racket application servers

2018-11-23 Thread Philip McGrath
I'm not familiar with Ruby, so this is just some general information.

The Racket web server already supports concurrency with its built-in green
threads, so handling one request won't block the concurrent handling of
another. (Not all languages' built-in web servers do this; I don't know
about Ruby in particular).

There isn't built-in support for parallelism, i.e. for taking advantage of
multiple processor cores. This isn't built in, and I don't personally need
this (my server only has two cores, and it runs a database and other
processes in addition to Racket). However, it is probably possible to
recreate the architecture you describe.

Essentially you would be running multiple instances of your application
behind a load-balancer. If you want to use nginx as a load balancer, that's
out of the equation; implementing a load-balancer in Racket would certainly
be possible but probably more work. Extra-linguistically, you could just
create a few systemd services or similar to run several totally separate
Racket instances. Within Racket, you would want to build on "places." You
can have N worker places running N instances of your application on N
OS-level threads, plus a master place to control them. A mechanism for
gracefully stopping the Racket web server is built in (see serve/launch/wait
).
Reloading isn't built in, but I've heard good things about the "reloadable"
package (https://pkgs.racket-lang.org/package/reloadable), which should let
you implement it if needed.

While I only run one instance of our application, I do use places to
redirect HTTP to HTTPS.

One caveat is that all of this assumes that, if you are using continuations
at all, you are using serializable continuations with `#lang web-server`.
Making places work well with native continuations would probably be a lot
of work, and it would probably be better to build that functionality into
the Racket web server than to try to fake it as a client.

-Philip


On Fri, Nov 23, 2018 at 3:46 PM 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?
>
> Thanks,
> Brian
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Racket application servers

2018-11-23 Thread Brian Adkins
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?

Thanks,
Brian

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Destructuring a list in (for ...)

2018-11-23 Thread Laurent
Maybe you could have something like (in-match ...) ?

On Fri, Nov 23, 2018 at 4:54 PM Alexis King  wrote:

> The trouble, sadly, is that this grammar is ambiguous. In
>
>   (for ([(x y) s])
> )
>
> should (x y) be parsed as a single match pattern or as two binders for a
> two-valued sequence (such as one produced by in-hash, for example)? You
> could make it unambiguous in various ways, such as by requiring uses of
> match patterns to all use the multi-valued binder syntax (with an extra set
> of parens), but that’s a bit clumsy. Unfortunately, I can’t think of any
> particularly elegant way to support match patterns in for loop binders in a
> backwards-compatible way.
>
> Alexis
>
> > On Nov 22, 2018, at 20:14, Greg Hendershott 
> wrote:
> >
> >> (define-syntax (match-for stx)
> >
> > That's nice.
> >
> > Sometimes I wish I could do the general thing -- use `match` patterns
> > in the binding clauses for any `for`-family form.
> >
> > I often do something like this:
> >
> >(define xs (list (cons 1 2) (cons 3 4)))
> >
> >(for ([x (in-list xs)])
> >  (match-define (cons a b) x)
> >  (use a b))
> >
> > Instead it would be nice to write:
> >
> >(for ([(match-define (cons a b)) (in-list xs)])
> >  (use a b))
> >
> > Or even just:
> >
> >(for ([(cons a b c) (in-list xs)])
> >  (use a b))
> >
> > In the grammar, `id` becomes `id-or-match-pattern`.
> >
> > On the other hand, this would only really help in simple
> > `match-define` destructuring -- as opposed to using `match` to handle
> > variations in the data. And although I do the former a lot, I do the
> > latter even more.
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Destructuring a list in (for ...)

2018-11-23 Thread Alexis King
The trouble, sadly, is that this grammar is ambiguous. In

  (for ([(x y) s])
)

should (x y) be parsed as a single match pattern or as two binders for a 
two-valued sequence (such as one produced by in-hash, for example)? You could 
make it unambiguous in various ways, such as by requiring uses of match 
patterns to all use the multi-valued binder syntax (with an extra set of 
parens), but that’s a bit clumsy. Unfortunately, I can’t think of any 
particularly elegant way to support match patterns in for loop binders in a 
backwards-compatible way.

Alexis

> On Nov 22, 2018, at 20:14, Greg Hendershott  wrote:
> 
>> (define-syntax (match-for stx)
> 
> That's nice.
> 
> Sometimes I wish I could do the general thing -- use `match` patterns
> in the binding clauses for any `for`-family form.
> 
> I often do something like this:
> 
>(define xs (list (cons 1 2) (cons 3 4)))
> 
>(for ([x (in-list xs)])
>  (match-define (cons a b) x)
>  (use a b))
> 
> Instead it would be nice to write:
> 
>(for ([(match-define (cons a b)) (in-list xs)])
>  (use a b))
> 
> Or even just:
> 
>(for ([(cons a b c) (in-list xs)])
>  (use a b))
> 
> In the grammar, `id` becomes `id-or-match-pattern`.
> 
> On the other hand, this would only really help in simple
> `match-define` destructuring -- as opposed to using `match` to handle
> variations in the data. And although I do the former a lot, I do the
> latter even more.

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.