Correct, and I should have added that in my case that only trivial
stuff was actually executed straight in the parent process, the more
hairy stuff was forked in the main, so a child calls the boss which
creates new children in order to avoid children of children (afaik the
db syncing only works with a single child "depth").

In main.l (the "boss"):

# workers
(de forkWorkHorse Args
   (unless (fork)
      (eval Args)

(de updatePresentFeed (Feed)
   (aImportCommon> '+Rss Feed)
   (commit 'upd)

(de updatePresentFeeds (Feeds)
   (for Feed Feeds
      (let Cycles 30
         (if (fork)
            (let Pid @
               (while (and (n0 Cycles) (kill Pid 0))
                  (dec 'Cycles)
                  (wait 1000))
               (kill Pid))
            (updatePresentFeed Feed)))))

The last updatePresentFees is actually an ugly (but robust) hack to
make up for the fact that some external sites would provide RSS input
that would crash the child, at this point I didn't have the time or
energy to figure out why, I simply wanted the import process to move
along and forget about it. Ie if something takes too long to finish we
kill it and go for the next in line.

In the child:

(dm aImportFleshLater> (Feed)
   (put!> Feed 'lastFetch (stamp> '+Gh))
   (let As (createArticles> This Feed T)
      (boss 'forkWorkHorse 'fleshArticles (lit As))

Here we import the articles so for instance the headlines display ASAP
for the user, other intensive meta data (data the user can wait for)
generation is handled through calling forkWorkHorse in main.l with the
appropriate data.

On Sat, Jun 2, 2012 at 3:23 PM, Alexander Burger <> wrote:
> Hi Henrik,
>> I don't know if the boss function might be of help to you? It helped
>> me in order for the current forked instance of the web server to be
> That's right.
> But I'd like to point out (again) that 'boss' must be used with absolute
> care. It executes expressions in the parent process, but the parent
> process is the central coordinator for child synchronization and IPC. It
> should always be as responsive as possible (because otherwise all
> children might be slowed down or even blocked), and it should never!
> crash.
> A crashing or blocking child process, on the other hand, doesn't do any
> harm to the rest of the system. Therefore, I strongly recommend to do
> any database modifications in a child process, as is the standard setup
> in all PicoLisp examples.
> Another reason for not putting any load on the parent process is: If the
> parent starts to do non-trivial work, it will increase its heap size. In
> the following, all fork'ed child processes will inherit this heap,
> including possible temporary data and cached objects. It is difficult
> then go get a predictable behavior.
> In a nutshell: Keep you hands off 'boss', unless you are absolutely sure
> what you are doing!
> Cheers,
> - Alex
> --

Reply via email to