[racket] distributed place messages: "write" isn't atomic
I have written a remote-server (as in
racket/place/define-remote-server), which I am then trying to use from a
web-server. The remote-server is running on a remote node (which is, in
fact, localhost).
The arguments to the RPC calls (from define-rpc) are fairly large
(including a serialised "request" object).
When RPC calls are made one at a time, the system works. However, when
enough stress is put upon the system (by me bashing at the refresh on
my web browser) to make two "simultaneous" RPC calls, the following
exception is thrown up:
------------------------------------------------------------------
UNKNOWN::2171: read: invalid structure description in `#s' form
context...:
/usr/local/racket/share/pkgs/distributed-places-lib/racket/place/distributed.rkt:392:8:
loop
[my call stack]
[my web-server].rkt:58:0: start
/usr/local/racket/share/pkgs/web-server-lib/web-server/dispatchers/dispatch-servlets.rkt:58:2
/usr/local/racket/collects/racket/private/more-scheme.rkt:162:2:
select-handler/no-breaks
/usr/local/racket/share/pkgs/web-server-lib/web-server/private/dispatch-server-unit.rkt:112:8
Servlet (@ /servlets/standalone.rkt) exception:
dcgm-type: contract violation
expected: dcgm?
given: 'cdgm
------------------------------------------------------------------
It seems that the RPC packets are overlapping. They are posted using
the following calls. Following the *channel-put call in the source
(distributed.rkt):
1529: *channel-put
411: place-socket-bridge% put-msg
716: sconn-write-flush
769: socket-connection% _write-flush
157: write-flush
161: write
That 'write' is bound to the 'write' from racket/base.
OK... back to my RPC call... the message I'm sending is composite; it is
a list of strings amongst others -- and I assume that the write is
written recursively to low-level output the components in parts. In
other words the write to the remote host is non-atomic, and not
synchronised.
My web-server (the Racket web-server) is multi-threaded, so I need some
means of synchronising this RPC write.
First -- am I missing something? (Given as the answer is usually yes,
it's a question well worth asking)
Has anyone else done this/encountered this?
Will a write of a single string suffer this?
In fact, on closer inspection - no matter what *I* do to make my
message atomic, sconn-write-flush writes a structure which I assume
will be written in bits.
Would a semaphore (or similar) around sconn-write-flush be the right
place/time for synchronising messages.
Also -- I notice that write-flush is defined as:
(define (write-flush msg [p (current-output-port)])
(flush-output)
(write msg p)
(flush-output p))
Should that first flush-output be on p?
Thanks, in advance, for your help with this.
Regards,
Tim
--
Tim Brown CEng MBCS <tim.brown at cityc.co.uk>
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
City Computing Limited · www.cityc.co.uk
City House · Sutton Park Rd · Sutton · Surrey · SM1 2AE · GB
T:+44 20 8770 2110 · F:+44 20 8770 2130
────────────────────────────────────────────────────────────────────────
City Computing Limited registered in London No:1767817.
Registered Office: City House, Sutton Park Road, Sutton, Surrey, SM1 2AE
VAT No: GB 918 4680 96