modules.using rewrite
parent
fe86d9f56e
commit
eb59431c3f
|
@ -0,0 +1,5 @@
|
||||||
|
USING: help.syntax help.markup modules.rpc-server modules.using ;
|
||||||
|
IN: modules.rpc-server
|
||||||
|
HELP: service
|
||||||
|
{ $syntax "IN: my-vocab service" }
|
||||||
|
{ $description "Allows words defined in the vocabulary to be used as remote procedure calls by " { $link POSTPONE: USING*: } } ;
|
|
@ -0,0 +1,34 @@
|
||||||
|
USING: accessors assocs concurrency.distributed
|
||||||
|
concurrency.messaging continuations effects init kernel
|
||||||
|
namespaces sequences sets threads vocabs vocabs.parser ;
|
||||||
|
IN: modules.rpc-server
|
||||||
|
<PRIVATE
|
||||||
|
TUPLE: rpc-request args vocabspec wordname ;
|
||||||
|
SYMBOL: serving-vocabs serving-vocabs [ V{ } clone ] initialize
|
||||||
|
|
||||||
|
: register-gets-thread ( -- )
|
||||||
|
[ receive [ data>> dup serving-vocabs get-global index
|
||||||
|
[ vocab-words [ stack-effect ] { } assoc-map-as ]
|
||||||
|
[ \ no-vocab boa ] if
|
||||||
|
] keep reply-synchronous
|
||||||
|
t ] "get-words" spawn-server "gets-thread" swap register-process ;
|
||||||
|
|
||||||
|
: register-does-thread ( -- )
|
||||||
|
[ receive [ data>> dup vocabspec>> serving-vocabs get-global index
|
||||||
|
[ [ args>> ] [ wordname>> ] [ vocabspec>> vocab-words ] tri at [ execute ] curry with-datastack ]
|
||||||
|
[ vocabspec>> \ no-vocab boa ] if
|
||||||
|
] keep reply-synchronous
|
||||||
|
t ] "do-word" spawn-server "does-thread" swap register-process ;
|
||||||
|
|
||||||
|
: register-loads-thread ( -- )
|
||||||
|
[ [ receive vocab ] keep reply-synchronous t ] "load-words" spawn-server "loads-thread" swap register-process ;
|
||||||
|
|
||||||
|
: add-vocabs-hook ( -- )
|
||||||
|
[ 9012 start-node
|
||||||
|
register-gets-thread
|
||||||
|
register-does-thread
|
||||||
|
register-loads-thread
|
||||||
|
] "start-serving-vocabs" add-init-hook ;
|
||||||
|
PRIVATE>
|
||||||
|
SYNTAX: service add-vocabs-hook
|
||||||
|
current-vocab name>> serving-vocabs get-global adjoin ;
|
|
@ -0,0 +1 @@
|
||||||
|
Serve factor words as rpcs
|
|
@ -0,0 +1,22 @@
|
||||||
|
USING: accessors assocs concurrency.distributed
|
||||||
|
concurrency.messaging fry generalizations io.sockets kernel
|
||||||
|
locals namespaces parser sequences vocabs vocabs.parser words ;
|
||||||
|
IN: modules.rpc
|
||||||
|
|
||||||
|
TUPLE: rpc-request args vocabspec wordname ;
|
||||||
|
|
||||||
|
: send-with-check ( message thread -- reply/* ) send-synchronous dup no-vocab? [ throw ] when ;
|
||||||
|
|
||||||
|
:: define-remote ( str effect addrspec vocabspec -- )
|
||||||
|
str create-in effect [ in>> length ] [ out>> length ] bi
|
||||||
|
'[ _ narray vocabspec str rpc-request boa "does-thread" addrspec 9012 <inet> <remote-process> send-with-check _ firstn ]
|
||||||
|
effect define-declared ;
|
||||||
|
|
||||||
|
:: remote-vocab ( addrspec vocabspec -- vocab )
|
||||||
|
vocabspec "-remote" append dup vocab [ dup set-current-vocab
|
||||||
|
vocabspec "gets-thread" addrspec 9012 <inet> <remote-process> send-with-check
|
||||||
|
[ first2 addrspec vocabspec define-remote ] each
|
||||||
|
] unless ;
|
||||||
|
|
||||||
|
: remote-load ( addr vocabspec -- voabspec ) [ swap
|
||||||
|
"loads-thread" swap 9012 <inet> <remote-process> send-synchronous ] keep [ dictionary get-global set-at ] keep ;
|
|
@ -0,0 +1 @@
|
||||||
|
Improved module import syntax with network transparency
|
|
@ -0,0 +1,13 @@
|
||||||
|
USING: help.syntax help.markup strings modules.using ;
|
||||||
|
IN: modules
|
||||||
|
ARTICLE: { "modules.using" "use" } "Using the modules.using vocab"
|
||||||
|
"This vocabulary defines " { $link POSTPONE: USING*: } " as an alternative to " { $link POSTPONE: USING: } " which makes qualified imports easier. "
|
||||||
|
"Secondly, it allows loading vocabularies from remote servers, as long as the remote vocabulary can be accessed at compile time. "
|
||||||
|
"Finally, the word can treat words in remote vocabularies as remote procedure calls. Any inputs are passed to the imported words as normal, and the result will appear on the stack- the only difference is that the word isn't called locally." ;
|
||||||
|
ABOUT: { "modules.using" "use" }
|
||||||
|
|
||||||
|
IN: syntax
|
||||||
|
HELP: USING*:
|
||||||
|
{ $syntax "USING: rpc-server::module fetch-sever:module { module qualified-name } { module => word ... } { qualified-module } { module EXCEPT word ... } { module word => importname } ;" }
|
||||||
|
{ $description "Adds vocabularies to the search path. Vocabularies can be loaded off a server or called as an rpc if preceded by a valid hostname. Bracketed pairs facilitate all types of qualified imports on both remote and local modules." }
|
||||||
|
"To use the 'USING*:' without explicitly importing modules.using first, add '\"modules.using\" require' to your .factor-boot-rc" ;
|
|
@ -0,0 +1,27 @@
|
||||||
|
USING: kernel modules.rpc peg peg-lexer peg.ebnf sequences
|
||||||
|
strings vocabs.parser ;
|
||||||
|
IN: modules.using
|
||||||
|
|
||||||
|
EBNF: modulize
|
||||||
|
tokenpart = (!(':').)+ => [[ >string ]]
|
||||||
|
s = ':' => [[ drop ignore ]]
|
||||||
|
rpc = tokenpart s s tokenpart => [[ first2 remote-vocab ]]
|
||||||
|
remote = tokenpart s tokenpart => [[ first2 remote-load ]]
|
||||||
|
module = rpc | remote | tokenpart
|
||||||
|
;EBNF
|
||||||
|
|
||||||
|
IN: syntax
|
||||||
|
ON-BNF: USING*:
|
||||||
|
tokenizer = <foreign factor>
|
||||||
|
sym = !(";"|"}"|"=>"|"EXCEPT").
|
||||||
|
modspec = sym => [[ modulize ]]
|
||||||
|
qualified-with = modspec sym => [[ first2 add-qualified ignore ]]
|
||||||
|
qualified = modspec => [[ dup add-qualified ignore ]]
|
||||||
|
from = modspec "=>" sym+ => [[ first3 nip add-words-from ignore ]]
|
||||||
|
exclude = modspec "EXCEPT" sym+ => [[ first3 nip add-words-excluding ignore ]]
|
||||||
|
rename = modspec sym "=>" sym => [[ first4 nip swapd add-renamed-word ignore ]]
|
||||||
|
long = "{" ( from | exclude | rename | qualified-with | qualified ) "}" => [[ drop ignore ]]
|
||||||
|
short = modspec => [[ use-vocab ignore ]]
|
||||||
|
wordSpec = long | short
|
||||||
|
using = wordSpec+ ";" => [[ drop ignore ]]
|
||||||
|
;ON-BNF
|
|
@ -1,4 +0,0 @@
|
||||||
USING: modules.rpc-server vocabs ;
|
|
||||||
IN: modules.remote-loading mem-service
|
|
||||||
|
|
||||||
: get-vocab ( vocabstr -- vocab ) vocab ;
|
|
|
@ -1 +0,0 @@
|
||||||
required for listeners allowing remote loading of modules
|
|
|
@ -1,45 +0,0 @@
|
||||||
USING: accessors assocs continuations effects io
|
|
||||||
io.encodings.binary io.servers.connection kernel
|
|
||||||
memoize namespaces parser sets sequences serialize
|
|
||||||
threads vocabs vocabs.parser words ;
|
|
||||||
IN: modules.rpc-server
|
|
||||||
|
|
||||||
SYMBOL: serving-vocabs V{ } clone serving-vocabs set-global
|
|
||||||
|
|
||||||
: do-rpc ( args word -- bytes )
|
|
||||||
[ execute ] curry with-datastack object>bytes ; inline
|
|
||||||
|
|
||||||
MEMO: mem-do-rpc ( args word -- bytes ) do-rpc ; inline
|
|
||||||
|
|
||||||
: process ( vocabspec -- )
|
|
||||||
vocab-words [ deserialize ] dip deserialize
|
|
||||||
swap at "executer" get execute( args word -- bytes ) write flush ;
|
|
||||||
|
|
||||||
: (serve) ( -- )
|
|
||||||
deserialize dup serving-vocabs get-global index
|
|
||||||
[ process ] [ drop ] if ;
|
|
||||||
|
|
||||||
: start-serving-vocabs ( -- )
|
|
||||||
[
|
|
||||||
binary <threaded-server>
|
|
||||||
5000 >>insecure
|
|
||||||
[ (serve) ] >>handler
|
|
||||||
start-server
|
|
||||||
] in-thread ;
|
|
||||||
|
|
||||||
: (service) ( -- )
|
|
||||||
serving-vocabs get-global empty? [ start-serving-vocabs ] when
|
|
||||||
current-vocab serving-vocabs get-global adjoin
|
|
||||||
"get-words" create-in
|
|
||||||
in get [ vocab vocab-words [ stack-effect ] { } assoc-map-as ] curry
|
|
||||||
(( -- words )) define-inline ;
|
|
||||||
|
|
||||||
SYNTAX: service \ do-rpc "executer" set (service) ;
|
|
||||||
SYNTAX: mem-service \ mem-do-rpc "executer" set (service) ;
|
|
||||||
|
|
||||||
load-vocab-hook [
|
|
||||||
[
|
|
||||||
dup words>> values
|
|
||||||
\ mem-do-rpc "memoize" word-prop [ delete-at ] curry each
|
|
||||||
] append
|
|
||||||
] change-global
|
|
|
@ -1 +0,0 @@
|
||||||
remote procedure call server
|
|
|
@ -1,26 +0,0 @@
|
||||||
USING: accessors compiler.units combinators fry generalizations io
|
|
||||||
io.encodings.binary io.sockets kernel
|
|
||||||
parser sequences serialize vocabs vocabs.parser words ;
|
|
||||||
IN: modules.rpc
|
|
||||||
|
|
||||||
DEFER: get-words
|
|
||||||
|
|
||||||
: with-in-vocab ( vocab quot -- vocab ) over
|
|
||||||
[ '[ _ set-current-vocab @ ] current-vocab name>> swap dip set-current-vocab ] dip vocab ; inline
|
|
||||||
|
|
||||||
: remote-quot ( addrspec vocabspec effect str -- quot )
|
|
||||||
'[ _ 5000 <inet> binary
|
|
||||||
[
|
|
||||||
_ serialize _ in>> length narray serialize _ serialize flush deserialize dup length firstn
|
|
||||||
] with-client
|
|
||||||
] ;
|
|
||||||
|
|
||||||
: define-remote ( addrspec vocabspec effect str -- ) [
|
|
||||||
[ remote-quot ] 2keep create-in -rot define-declared word make-inline
|
|
||||||
] with-compilation-unit ;
|
|
||||||
|
|
||||||
: remote-vocab ( addrspec vocabspec -- vocab )
|
|
||||||
dup "-remote" append [
|
|
||||||
[ (( -- words )) [ "get-words" remote-quot ] keep call-effect ] 2keep
|
|
||||||
[ rot first2 swap define-remote ] 2curry each
|
|
||||||
] with-in-vocab ;
|
|
|
@ -1 +0,0 @@
|
||||||
Sam Anklesaria
|
|
|
@ -1 +0,0 @@
|
||||||
module pushing in remote-loading listeners
|
|
|
@ -1,5 +0,0 @@
|
||||||
USING: assocs modules.rpc-server vocabs
|
|
||||||
modules.remote-loading words ;
|
|
||||||
IN: modules.uploads service
|
|
||||||
|
|
||||||
: upload-vocab ( word binary -- ) \ get-vocab "memoize" word-prop set-at ;
|
|
|
@ -1 +0,0 @@
|
||||||
Sam Anklesaria
|
|
|
@ -1 +0,0 @@
|
||||||
improved module import syntax
|
|
|
@ -1 +0,0 @@
|
||||||
unportable
|
|
|
@ -1,3 +0,0 @@
|
||||||
USING: modules.rpc-server io.servers.connection ;
|
|
||||||
IN: modules.test-server service
|
|
||||||
: rpc-hello ( -- str ) "hello world" stop-this-server ;
|
|
|
@ -1,4 +0,0 @@
|
||||||
QUALIFIED-WITH: modules.using m
|
|
||||||
IN: modules.using.tests
|
|
||||||
m:USING: tools.test localhost::modules.test-server ;
|
|
||||||
[ "hello world" ] [ rpc-hello ] unit-test
|
|
|
@ -1,15 +0,0 @@
|
||||||
USING: modules.rpc-server help.syntax help.markup strings ;
|
|
||||||
QUALIFIED-WITH: modules.using m
|
|
||||||
IN: modules
|
|
||||||
|
|
||||||
HELP: service
|
|
||||||
{ $syntax "IN: module service" }
|
|
||||||
{ $description "Starts a server for requests for remote procedure calls." } ;
|
|
||||||
|
|
||||||
ARTICLE: { "modules" "remote-loading" } "Using the remote-loading vocabulary"
|
|
||||||
"If loaded, starts serving vocabularies, accessable through a " { $link POSTPONE: m:USING: } " form" ;
|
|
||||||
|
|
||||||
HELP: USING:
|
|
||||||
{ $syntax "USING: rpc-server::module fetch-sever::module { module qualified-name } { module => word ... } ... ;" }
|
|
||||||
{ $description "Adds vocabularies to the front of the search path. Vocabularies can be fetched remotely, if preceded by a valid hostname. Name pairs facilitate imports like in the "
|
|
||||||
{ $link POSTPONE: QUALIFIED: } " or " { $link POSTPONE: FROM: } " forms." } ;
|
|
|
@ -1,36 +0,0 @@
|
||||||
USING: accessors assocs kernel modules.remote-loading modules.rpc
|
|
||||||
namespaces peg peg.ebnf peg-lexer sequences vocabs vocabs.parser
|
|
||||||
strings ;
|
|
||||||
IN: modules.using
|
|
||||||
|
|
||||||
: >qualified ( vocab prefix -- assoc )
|
|
||||||
[ vocab-words ] [ 58 suffix ] bi* [ swap [ prepend ] dip ] curry assoc-map ;
|
|
||||||
|
|
||||||
: >partial-vocab ( words assoc -- assoc )
|
|
||||||
[ dupd at [ no-word-error ] unless* ] curry { } map>assoc ;
|
|
||||||
|
|
||||||
: remote-load ( addr vocabspec -- voab ) [ "modules.remote-loading" remote-vocab use-vocab ] dip get-vocab ;
|
|
||||||
|
|
||||||
: load'em ( vocab words/? -- ) [ swap >partial-vocab ] when* manifest get qualified-vocabs>> push ;
|
|
||||||
|
|
||||||
EBNF: modulize
|
|
||||||
tokenpart = (!(':').)+ => [[ >string ]]
|
|
||||||
s = ':' => [[ drop ignore ]]
|
|
||||||
rpc = tokenpart s s tokenpart => [[ first2 remote-vocab ]]
|
|
||||||
remote = tokenpart s tokenpart => [[ first2 remote-load ]]
|
|
||||||
plain = tokenpart => [[ load-vocab ]]
|
|
||||||
module = rpc | remote | plain
|
|
||||||
;EBNF
|
|
||||||
|
|
||||||
ON-BNF: USING:
|
|
||||||
tokenizer = <foreign factor>
|
|
||||||
sym = !(";"|"}"|"=>").
|
|
||||||
modspec = sym => [[ modulize ]]
|
|
||||||
qualified = modspec sym => [[ first2 >qualified ]]
|
|
||||||
unqualified = modspec => [[ vocab-words ]]
|
|
||||||
words = ("=>" sym+ )? => [[ [ f ] [ second ] if-empty ]]
|
|
||||||
long = "{" ( qualified | unqualified ) words "}" => [[ rest first2 load'em ignore ]]
|
|
||||||
short = modspec => [[ use-vocab ignore ]]
|
|
||||||
wordSpec = long | short
|
|
||||||
using = wordSpec+ ";" => [[ drop ignore ]]
|
|
||||||
;ON-BNF
|
|
Loading…
Reference in New Issue