Hi Rick,

> > and the load distributed across multiple servers.
> 
> How so? Currently PicoLisp forks on the same sever. Are you using remote
> queries to other PicoLisp instances? A proxy to parse routes?

Sure, kind of. See e.g.

   http://software-lab.de/doc/refR.html#remote/2

You can easily "fork" to other servers, but then you must do explicit
RPC (as opposed to the built-in one that you get with (fork)). Excerpts
from a distributed shop system (without striving for completeness, just
to get an idea):

   (class +Shop +Entity)
   (rel id (+Need +Key +Number))                   # Client-ID
   (rel ip (+String))                              # Host-IP
   (rel dom (+String))                             # Domain
   (rel cat (+List +Ref +String))                  # Categories
   (rel nm (+IdxFold +String))                     # Name
   ...

   (dm pid> ()
      (when (: ip)
         (cdr (assoc (: id) (shops @))) ) )

   (dm start> ()
      (call "ssh" (: ip)
         (pack
            "cd " (pwd) "; "
            "./pil myApp/shop/main.l "
            (: id)
            " "
            (sym (: nm))
            " lib/app.l -main -go -wait >>log/"
            (+ 3000 (: id))
            " 2>&1 &" ) ) )

   (dm stop> ()
      (when (pid> This)
         (call "ssh" (: ip) (pack "kill " @)) ) )

   (dm sock> ()
      (if (asoq This *ShopSocks)
         (cdar (rot *ShopSocks (index @ *ShopSocks)))
         (let? S (connect (: ip) (+ 4000 (: id)))
            (push '*ShopSocks (cons This S))
            (let? L (nth *ShopSocks 4)
               (when (cdr L)
                  (close (cdar @))
                  (con L) ) )
            S ) ) )

   (dm rsrc> ()
      (let? @Sock (connect (: ip) (+ 4000 (: id)))
         (let? L (nth *RsrcSocks 3)
            (when (cdr L)
               (close (car @))
               (con L) ) )
         (push '*RsrcSocks @Sock)
         (let @Ext (+ `*DbsMax (* `*RemoteDbsMax (: id)))
            (cons
               (curry (@Ext @Sock) (X)  # out
                  (ext @Ext
                     (out @Sock (pr X)) ) )
               (curry (@Ext @Sock) ()  # in
                  (when (index @Sock *RsrcSocks)
                     (rot *RsrcSocks @)
                     (ext @Ext
                        (or
                           (in @Sock (rd))
                           (nil (close @Sock) (pop '*RsrcSocks)) ) ) ) ) ) ) ) )

   (dm query> @
      (let? Sock (sock> This)
         (ext (+ `*DbsMax (* `*RemoteDbsMax (: id)))
            (out Sock (pr (rest)))
            (rdShop Sock) ) ) )

   ...

   # Article
   (class +Art +Entity)
   (rel shop (+Hook +Aux +Ref +Link)               # Shop
      (id)
      NIL (+Shop) )
   (rel id (+Ref +Number))                         # ID
   (rel nm (+Hook2 +IdxFold +String) 3 shop)       # Name
   (rel grp (+Hook2 +IdxFold +String) 3 shop)      # Group
   (rel ts (+Hook2 +Ref +Bag)                      # Timestamp
      shop
      ((+Date))
      ((+Time)) )
   (rel pr (+Ref +Number) NIL 2)                   # Price
   (rel rp (+Ref +Number) shop 2)                  # Regular price
   ...

   (dm get> @
      (and
         (query> (: shop) 'id '(db: +Art) (: id))
         (pass get @) ) )

   ...

   (de remoteShopSearch (Lst)
      (list
         '@Rsrc '(cons (rsrc> *DirectShop))
         '@Cat *CatSearch
         '@Grp *GrpSearch
         '@Lim (and *PrLimit (lit (cons NIL @)))
         (list 'remote '(@A . @Rsrc)
            (cons 'select '(@A)
               (conc
                  (mapcar
                     '((W) (list 'nm '+Art W))
                     Lst )
                  (quote
                     (cat +Grp @Cat (grp +Art))
                     (key +Grp @Grp (grp +Art))
                     (pr +Art @Lim) ) )
               (conc
                  (mapcar
                     '((W) (list 'part W '@A 'nm))
                     Lst )
                  (quote
                     (same @Cat @A grp cat)
                     (same @Grp @A grp key)
                     (range @Lim @A pr) ) ) ) )
         '(@@ aux 'shop '+Art *DirectShop (id (-> @A))) ) )

   ...

   # Find remote shop processes
   (off "Shops")

   (de shops (IP)
      (cdr
         (or (assoc IP "Shops")
         (push '"Shops"
            (cons IP
               (in
                  (list
                     "ssh" IP
                     "ps --no-headers -o pid,cmd $(pgrep -f myApp/shop/main.l)" 
)
                  (make
                     (while (read)
                        (let Pid @
                           (skip)
                           (when (= "./bin/picolisp" (till " " T))
                              (from "main.l ")
                              (link (cons (read) Pid)) )
                           (line T) ) ) ) ) ) ) ) ) )

   (de shops- (IP)
      (setq "Shops" (delete (assoc IP "Shops") "Shops")) )

   # RPC Commands
   (de updArt (Shop Id . Args)
      (when (db 'id '+Shop Shop)
         (dbSync)
         (with
            (or
               (aux 'shop '+Art @ Id)
               (new (db: +Art) '(+Art) 'shop @ 'id Id) )
            (while Args
               (put> This (pop 'Args) (pop 'Args)) )
            (put> This 'ts (list (date) (time T))) )
         (commit 'upd) ) )

   ...

   # Remote queries
   (de rdShop (Sock)
      (let X (in Sock (rd "EOF"))
         (ifn (== "EOF" X)
            X
            (close Sock)
            (setq *ShopSocks
               (filter '((X) (<> Sock (cdr X)))
                  *ShopSocks ) )
            NIL ) ) )

   (de *Ext
      (`*DbsMax .
         ((Obj)
            (with (db 'id '+Shop (/ (- (car (id Obj T)) `*DbsMax) 
`*RemoteDbsMax))
               (let? Sock (sock> This)
                  (ext (+ `*DbsMax (* `*RemoteDbsMax (: id)))
                     (out Sock (pr (cons 'qsym Obj)))
                     (rdShop Sock) ) ) ) ) ) )


> re: "https://www.mail-archive.com/picolisp@software-lab.de/msg00097.html";

Yes, correct.


> How does fries.js GET and POST to PicoLisp? JSON converted to PicoLisp
> objects?

No. We only modified/extended "@lib/form.js", so that it emulates the
browser behavior, and dynamically (re)builds the whole DOM (because the
whole app must be "single-page") instead of just the field values. On
the server side nothing changed. The app is proprietary, I hope I can
write more about that at some future time.

♪♫ Alex
-- 
UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe

Reply via email to