factor/basis/io/servers/connection/connection.factor

167 lines
4.3 KiB
Factor
Raw Normal View History

! Copyright (C) 2003, 2009 Slava Pestov.
2008-06-17 01:04:18 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: continuations destructors kernel math math.parser
namespaces parser sequences strings prettyprint
2008-09-22 17:09:10 -04:00
quotations combinators logging calendar assocs present
2008-06-17 01:04:18 -04:00
fry accessors arrays io io.sockets io.encodings.ascii
io.sockets.secure io.files io.streams.duplex io.timeouts
2008-09-22 17:09:10 -04:00
io.encodings threads make concurrency.combinators
2008-06-25 17:58:19 -04:00
concurrency.semaphores concurrency.flags
2009-03-16 21:11:36 -04:00
combinators.short-circuit ;
2008-06-17 01:04:18 -04:00
IN: io.servers.connection
TUPLE: threaded-server
2009-06-15 14:07:15 -04:00
name
log-level
secure
insecure
secure-config
sockets
2008-06-17 01:04:18 -04:00
max-connections
semaphore
2009-06-15 14:07:15 -04:00
timeout
2008-06-17 01:04:18 -04:00
encoding
2009-06-15 14:07:15 -04:00
handler
ready ;
2008-06-17 01:04:18 -04:00
: local-server ( port -- addrspec ) "localhost" swap <inet> ;
: internet-server ( port -- addrspec ) f swap <inet> ;
: new-threaded-server ( encoding class -- threaded-server )
2008-06-17 01:04:18 -04:00
new
2009-06-15 14:07:15 -04:00
"server" >>name
DEBUG >>log-level
<secure-config> >>secure-config
V{ } clone >>sockets
1 minutes >>timeout
[ "No handler quotation" throw ] >>handler
<flag> >>ready
swap >>encoding ;
2008-06-17 01:04:18 -04:00
: <threaded-server> ( encoding -- threaded-server )
2008-06-17 01:04:18 -04:00
threaded-server new-threaded-server ;
2008-08-30 16:25:53 -04:00
GENERIC: handle-client* ( threaded-server -- )
2008-06-17 01:04:18 -04:00
<PRIVATE
: >insecure ( addrspec -- addrspec' )
dup { [ integer? ] [ string? ] } 1|| [ internet-server ] when ;
: >secure ( addrspec -- addrspec' )
>insecure
dup { [ secure? ] [ not ] } 1|| [ <secure> ] unless ;
: listen-on ( threaded-server -- addrspecs )
[ secure>> >secure ] [ insecure>> >insecure ] bi
[ resolve-host ] bi@ append ;
2008-09-22 17:09:10 -04:00
: accepted-connection ( remote local -- )
[
[ "remote: " % present % ", " % ]
[ "local: " % present % ]
bi*
] "" make
\ accepted-connection NOTICE log-message ;
2008-06-17 01:04:18 -04:00
: log-connection ( remote local -- )
2008-09-22 17:09:10 -04:00
[ accepted-connection ]
2008-06-17 01:04:18 -04:00
[ [ remote-address set ] [ local-address set ] bi* ]
2bi ;
M: threaded-server handle-client* handler>> call( -- ) ;
2008-06-17 01:04:18 -04:00
: handle-client ( client remote local -- )
'[
2008-09-10 23:11:40 -04:00
_ _ log-connection
2008-06-17 01:04:18 -04:00
threaded-server get
[ timeout>> timeouts ] [ handle-client* ] bi
] with-stream ;
\ handle-client NOTICE add-error-logging
2008-09-28 18:56:44 -04:00
2008-06-17 01:04:18 -04:00
: thread-name ( server-name addrspec -- string )
2008-12-03 20:10:41 -05:00
unparse-short " connection from " glue ;
2008-06-17 01:04:18 -04:00
2008-08-30 16:25:53 -04:00
: accept-connection ( threaded-server -- )
2008-06-17 01:04:18 -04:00
[ accept ] [ addr>> ] bi
2008-09-10 23:11:40 -04:00
[ '[ _ _ _ handle-client ] ]
2008-06-17 01:04:18 -04:00
[ drop threaded-server get name>> swap thread-name ] 2bi
spawn drop ;
2008-08-30 16:25:53 -04:00
: accept-loop ( threaded-server -- )
2008-06-17 01:04:18 -04:00
[
threaded-server get semaphore>>
[ [ accept-connection ] with-semaphore ]
[ accept-connection ]
if*
] [ accept-loop ] bi ;
2008-06-17 01:04:18 -04:00
2008-08-30 16:25:53 -04:00
: started-accept-loop ( threaded-server -- )
2008-06-25 17:58:19 -04:00
threaded-server get
[ sockets>> push ] [ ready>> raise-flag ] bi ;
: start-accept-loop ( addrspec -- )
2008-06-17 01:04:18 -04:00
threaded-server get encoding>> <server>
2008-06-25 17:58:19 -04:00
[ started-accept-loop ] [ [ accept-loop ] with-disposal ] bi ;
2008-06-17 01:04:18 -04:00
2008-10-03 02:12:50 -04:00
\ start-accept-loop NOTICE add-error-logging
2008-06-17 06:21:45 -04:00
2008-06-17 01:04:18 -04:00
: init-server ( threaded-server -- threaded-server )
dup semaphore>> [
dup max-connections>> [
<semaphore> >>semaphore
] when*
] unless ;
: (start-server) ( threaded-server -- )
init-server
dup threaded-server [
[ ] [ name>> ] bi [
[ listen-on [ start-accept-loop ] parallel-each ]
[ ready>> raise-flag ]
bi
] with-logging
] with-variable ;
2008-06-17 01:04:18 -04:00
PRIVATE>
: start-server ( threaded-server -- )
#! Only create a secure-context if we want to listen on
#! a secure port, otherwise start-server won't work at
#! all if SSL is not available.
dup secure>> [
dup secure-config>> [
(start-server)
] with-secure-context
] [
(start-server)
] if ;
2008-06-17 01:04:18 -04:00
2008-06-25 17:58:19 -04:00
: wait-for-server ( threaded-server -- )
ready>> wait-for-flag ;
: start-server* ( threaded-server -- )
[ [ start-server ] curry "Threaded server" spawn drop ]
[ wait-for-server ]
bi ;
2008-10-02 09:30:38 -04:00
: stop-server ( threaded-server -- )
[ f ] change-sockets drop dispose-each ;
: stop-this-server ( -- )
threaded-server get stop-server ;
2008-06-17 01:04:18 -04:00
GENERIC: port ( addrspec -- n )
M: integer port ;
M: object port port>> ;
: secure-port ( -- n )
threaded-server get dup [ secure>> port ] when ;
: insecure-port ( -- n )
threaded-server get dup [ insecure>> port ] when ;