[racket] network server with places?
OK, scheme_get_port_fd() seems consistently to return -1 for ports
returned by tcp-accept, so I'm trying instead to use
scheme_get_port_socket() and scheme_socket_to_ports(). However, when I
attempt to write to the resulting output port, I'm told that I'm
writing to an invalid file descriptor. Example code follows:
Module: listener.rkt
==============
#lang racket
(require ffi/unsafe)
(define _dup
(get-ffi-obj "dup" #f (_fun _int -> _int)))
(define port->socket
(get-ffi-obj "scheme_get_port_socket" #f (_fun _racket (r : (_ptr o
_int)) -> _int -> r)))
(define (tcp-accept/socket listener)
(let*-values (((in out) (tcp-accept listener))
((socket) (_dup (port->socket in))))
socket))
(define listener (tcp-listen 6667))
(define w (place "worker.rkt" 'init))
(let loop ()
(let ((socket (tcp-accept/socket listener)))
(place-channel-send w socket))
(loop))
========================
Module: worker.rkt
=======================
#lang racket
(provide init)
(require ffi/unsafe)
(define socket->ports
(get-ffi-obj "scheme_socket_to_ports" #f
(_fun (_ptr i _int)
(_racket = #f)
(_int = 1)
(in : (_ptr o _racket))
(out : (_ptr o _racket))
-> _void
-> (values in out))))
(define (init ch)
(let ((socket (place-channel-receive ch)))
(let-values (((in out) (socket->ports socket)))
(write-string "Welcome\n" out)
(flush-output out)
(let ((str (read-line in)))
(write-string str out)
(close-input-port in)
(close-output-port out)))))
On Mon, Jun 6, 2011 at 12:46 PM, Jon Zeppieri <zeppieri at gmail.com> wrote:
> Thanks! -J
>
>
> On Mon, Jun 6, 2011 at 9:24 AM, Matthew Flatt <mflatt at cs.utah.edu> wrote:
>> I think places should somehow provide better support for this task.
>>
>> For now, using the FFI you could use scheme_get_port_fd() to extract a
>> TCP port's file descriptor as an integer, dup() it, send the dup()ed
>> integer to another place, and create new ports using
>> scheme_make_fd_input_port() and scheme_make_fd_output_port() on the
>> dup()ed file descriptor in the new place, and then close the TCP ports
>> in the original place.
>>
>> At Sun, 5 Jun 2011 21:50:22 -0400, Jon Zeppieri wrote:
>>> On Sun, Jun 5, 2011 at 9:39 PM, Robby Findler
>>> <robby at eecs.northwestern.edu> wrote:
>>> > I don't know about the feasibility of making one of those marshall
>>> > across a place channel but in the meantime does it make sense for you
>>> > to read the request on the main place, send the data to a separate
>>> > place to process and the send the result back? Or is most of the work
>>> > in reading and writing the data?
>>>
>>> Well, that's what I meant by "handling all socket I/O in the 'main'
>>> place," and I'm afraid that's exactly what I want to avoid doing.
>>>
>>> -Jon
>>>
>>>
>>> >
>>> > Robby
>>> >
>>> > On Sunday, June 5, 2011, Jon Zeppieri <zeppieri at gmail.com> wrote:
>>> >> Is there a way to write a network server using places, where separate
>>> >> client connections would be handled by separate worker places? Since
>>> >> neither TCP listeners nor ports can be sent over a place-channel, I
>>> >> can't figure out a way of doing this short of handling all socket I/O
>>> >> in the "main" place --- the one that manages the listener.
>>> >>
>>> >> What I'd like is either for the workers to accept their own
>>> >> connections (but that would require a shared listener) or to have the
>>> >> main place accept connections but hand them off to the workers. I
>>> >> don't know if there is any way to accomplish this right now, and if
>>> >> there isn't, I don't know what the right approach would be.
>>> >>
>>> >> -Jon
>>> >> _________________________________________________
>>> >> For list-related administrative tasks:
>>> >> http://lists.racket-lang.org/listinfo/users
>>> >>
>>> >
>>>
>>> _________________________________________________
>>> For list-related administrative tasks:
>>> http://lists.racket-lang.org/listinfo/users
>>
>