219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
#f))
(define (udat-captain-host-port udata)
(if (and (udat-captain-address udata)(udat-captain-port udata))
(conc (udat-captain-address udata) ":" (udat-captain-port udata))
#f))
;; struct for keeping track of others we are talking to
(defstruct peer
(addr-port #f)
(hostname #f)
(pid #f)
(inp #f)
(oup #f)
(dbs '()) ;; list of databases this peer is currently handling
)
(defstruct work
(peer-dat #f)
(handlerkey #f)
(qrykey #f)
|
>
>
>
|
|
|
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
#f))
(define (udat-captain-host-port udata)
(if (and (udat-captain-address udata)(udat-captain-port udata))
(conc (udat-captain-address udata) ":" (udat-captain-port udata))
#f))
(define (udat-get-peer udata host-port)
(hash-table-ref/default (udat-peers udata) host-port #f))
;; struct for keeping track of others we are talking to
(defstruct peer
(addr-port #f)
(hostname #f)
(pid #f)
;; (inp #f)
;; (oup #f)
(dbs '()) ;; list of databases this peer is currently handling
)
(defstruct work
(peer-dat #f)
(handlerkey #f)
(qrykey #f)
|
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
(udat-serv-listener-set! udata tlsn)
udata))
(define (get-peer-dat udata host-port #!optional (hostname #f)(pid #f))
;; I'm currently very fuzzy on whether it makes sense to be reusing the outgoing connections.
;; at the other end of the line I think the reciever has closed the ports - thus each message
;; requires new connection?
(let* ((pdat (or #f #;(hash-table-ref/default (udat-outgoing-conns udata) host-port #f)
(handle-exceptions ;; ERROR - MAKE THIS EXCEPTION HANDLER MORE SPECIFIC
exn
#f
(let ((npdat (make-peer addr-port: host-port)))
(if hostname (peer-hostname-set! npdat hostname))
(if pid (peer-pid-set! npdat pid))
(let-values (((ninp noup)(tcp-connect host-port)))
(peer-inp-set! npdat ninp)
(peer-oup-set! npdat noup))
(hash-table-set! (udat-outgoing-conns udata) host-port npdat)
npdat)))))
pdat))
(define (get-peer-ports udata host-port #!optional (hostname #f)(pid #f))
(let ((pdat (get-peer-dat udata host-port hostname pid)))
(if pdat
(values (peer-inp pdat)(peer-oup pdat))
(values #f #f))))
;; send structured data to recipient
;;
;; NOTE: qrykey is what was called the "cookie" previously
;;
;; retval tells send to expect and wait for return data (one line) and return it or time out
;; this is for ping where we don't want to necessarily have set up our own server yet.
;;
(define (send udata host-port handler qrykey data #!key (hostname #f)(pid #f)(params '())(retval #f))
(let-values (((inp oup)(get-peer-ports udata host-port hostname pid)))
;;
;; CONTROL LINE: (note: removed the hostname - I don't think it adds much value
;;
;; handlerkey host:port pid qrykey params ...
;;
(if (and inp oup)
(let* ((myhost (udat-my-address udata))
(myport (udat-my-port udata))
(dat (conc
handler " "
(udat-my-address udata) ":" (udat-my-port udata) " "
;; (udat-my-hostname udata) " "
(udat-my-pid udata) " "
qrykey
(if (null? params) "" (conc " " (string-intersperse params " "))))))
(if (and myhost myport)
(begin
(write-line dat oup)
(write-line data oup)
;; (print "Sent dat: " dat " data: " data)
(if retval
(read-line inp)
#t))
(begin
(print "ERROR: send called but no receiver has been setup. Please call setup first!")
#f))
;; NOTE: DO NOT BE TEMPTED TO LOOK AT ANY DATA ON INP HERE!
;; (there is a listener for handling that)
)
#f))) ;; #f means failed to connect and send
;; send a request to the given host-port and register a mailbox in udata
;; wait for the mailbox data and return it
;;
(define (send-receive udata host-port handler qrykey data #!key (hostname #f)(pid #f)(params '())(timeout 20))
(let ((mbox (make-mailbox))
(mbox-time (current-milliseconds))
|
|
<
<
<
<
<
<
<
<
<
<
>
>
>
|
|
|
<
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
|
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
|
(udat-serv-listener-set! udata tlsn)
udata))
(define (get-peer-dat udata host-port #!optional (hostname #f)(pid #f))
;; I'm currently very fuzzy on whether it makes sense to be reusing the outgoing connections.
;; at the other end of the line I think the reciever has closed the ports - thus each message
;; requires new connection?
(let* ((pdat (or (udat-get-peer udata host-port)
(handle-exceptions ;; ERROR - MAKE THIS EXCEPTION HANDLER MORE SPECIFIC
exn
#f
(let ((npdat (make-peer addr-port: host-port)))
(if hostname (peer-hostname-set! npdat hostname))
(if pid (peer-pid-set! npdat pid))
npdat)))))
pdat))
;; send structured data to recipient
;;
;; NOTE: qrykey is what was called the "cookie" previously
;;
;; retval tells send to expect and wait for return data (one line) and return it or time out
;; this is for ping where we don't want to necessarily have set up our own server yet.
;;
(define (send udata host-port handler qrykey data #!key (hostname #f)(pid #f)(params '())(retval #f))
(handle-exceptions ;; ERROR - MAKE THIS EXCEPTION HANDLER MORE SPECIFIC
exn
#f
(let-values (((inp oup)(tcp-connect host-port)))
;;
;; CONTROL LINE:
;; handlerkey host:port pid qrykey params ...
;;
(let ((res
(if (and inp oup)
(let* ((myhost (udat-my-address udata))
(myport (udat-my-port udata))
(dat (conc
handler " "
(udat-my-address udata) ":" (udat-my-port udata) " "
;; (udat-my-hostname udata) " "
(udat-my-pid udata) " "
qrykey
(if (null? params) "" (conc " " (string-intersperse params " "))))))
(if (and myhost myport)
(begin
(write-line dat oup)
(write-line data oup)
;; (print "Sent dat: " dat " data: " data)
(if retval
(read-line inp)
#t))
(begin
(print "ERROR: send called but no receiver has been setup. Please call setup first!")
#f))
;; NOTE: DO NOT BE TEMPTED TO LOOK AT ANY DATA ON INP HERE!
;; (there is a listener for handling that)
)
#f))) ;; #f means failed to connect and send
(close-input-port inp)
(close-output-port oup)
res))))
;; send a request to the given host-port and register a mailbox in udata
;; wait for the mailbox data and return it
;;
(define (send-receive udata host-port handler qrykey data #!key (hostname #f)(pid #f)(params '())(timeout 20))
(let ((mbox (make-mailbox))
(mbox-time (current-milliseconds))
|