I'll see what I can do, thanks for the help and happy holidays!
On Mon, Dec 26, 2011 at 10:57 PM, Alexander Burger <a...@software-lab.de> wrote: > Hi Henrik, > >> So I've tried the remote pilog stuff out now (better late than never). > > Good :) > >> I've attached a simple project (needs to be extracted to >> /opt/picolisp/projects/). >> >> Very cool stuff, indeed. >> >> You start by running: >> /p projects/remote-test/remote.l -go 1 >> /p projects/remote-test/remote.l -go 2 >> /p projects/remote-test/main.l > > Please let me first post two general notes: > > 1. The 'p' script was deprecated some time ago, and doesn't come with > the PicoLisp releases any longer. > > The recommended startup command is 'pil', with an optional '+' at the > end of the command line for debug mode. Then you don't need to load > "dbg.l" and "lib/debug.l". > > "lib/misc.l" is automatically included, so that only "@lib/http.l" > must be explicitly loaded in the first lines of "remote.l" and > "main.l". > > 2. Since earlier this year, it is necessary to call 'tell' after an > explicit 'sync' (see "doc/refS.html#sync"). So line 18 in "remote.l" > holds the expression > > (while (rd) > (sync) > (tell) > (out Sock > (pr (eval @)) ) ) ) > > >> I have three questions: >> >> 1.) The result of insertTestData on line 50 in main.l is that only it >> manages to insert Jane and John in the remotes, it's as if they need >> to be wakened up by the first query that fails, any idea of why this >> happens and how to prevent it? > > This is a synchronization problem. As I have pointed out before, the > parent process has the duty of coordinating the communication between > the child processes, and should do as little other work as possible. > Everything, from DB manipulations to GUI interfacing, should be done in > child processes. > > For that reason, the 'go' function traditionally calls (rollback) > immediately before starting the main event (usually (wait)), so that > every spawned child process gets a virgin environment, without possibly > cached object's inherited from the parent. > > However, in 'go' in "remote.l", you have > > ... > (pool (pack *DbDir *IdxNum)) > (rollback) > (mapc show (collect 'uname '+User)) > (task (port (+ *IdxNum 4040)) > ... > > The problematic line here is the 'collect'. It causes the parent to > pollute its cache with objects from the DB. Especially, this contains > the *DB root object. As a result, each child starts with this pre-cached > and partially filled root object. > > I would write 'go' as > > (pool (pack *DbDir *IdxNum)) > (mapc show (collect 'uname '+User)) > (task (port (+ *IdxNum 4040)) > (let? Sock (accept @) > (unless (fork) > (in Sock > (while (rd) > (sync) > (tell) > (out Sock > (pr (eval @)) ) ) ) > (bye) ) > (close Sock) ) ) > (forked) > (rollback) ) > > i.e. move down the (rollback), and take care that the parents doesn't do > anything else than calling (wait) after that. > > >> 2.) This is OT but I noticed that +Key (which the reference says is >> unique) is not respected, I am able to insert several John for >> instance. > > Right. '+Key' maintains a unique index. If you do two inserts into that > tree, with the same key but two different values, the second one will > remain. > > Consistency of objects referred to by that tree and their values are > handled at higher levels. For example, the GUI will check that, and > won't allow the user to give a value to an object which is already > indexed by some other object. > >> Is (request) the only way to get around this or? This has >> probably been discussed on a number of earlier occasions but >> unfortunately my memory is weak. > > Yes. 'request' and 'new' are different in this regard. 'request' > basically first searches for the key combination, and uses the existing > object if found, otherwise calls 'new'. > > If you call 'new' two times with the same key value, you'll get two > objects and an inconsistent index. (dbCheck) will indicate an error in > that case. > > >> 3.) How much work would it be to implement put!>> and lose!>> that >> somehow infers where an object comes from in order to perform those >> operations? It seems to me there are two steps to solving that problem > > Not sure about the concrete case. The interprocess communication > protocoll must include additional information from the originating > machine (some key per machine) which can be stored along with the > object. I don't see that we need some special function like 'put!>>' for > that. > >> that should not be impossible to overcome, first inferring which >> server the object belongs to with the help of the file offset, then >> somehow going back to the original, ie {Y} -> {X} and then executing >> the put or lose remotely with the help of {X}. > > Yes, this sounds feasible to me, though the above idea of simply passing > information from the sender might be easier. > > Cheers, > - Alex > -- > UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe