[racket] network server with places?

From: Jon Zeppieri (zeppieri at gmail.com)
Date: Tue Jun 7 00:45:52 EDT 2011

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
>>
>



Posted on the users mailing list.