So I gather the *Ext mapping is absolutely necessary regardless of whether
remote or ext is used.

I took at the *Ext section again, could I use this maybe:

(setq *Ext  # Define extension functions
      '((@Host @Port @Ext)
         (let Sock NIL
            (cons @Ext
               (curry (@Host @Ext Sock) (Obj)
                  (when (or Sock (setq Sock (connect @Host @Port)))
                     (ext @Ext
                        (out Sock (pr (cons 'qsym Obj)))
                        (prog1 (in Sock (rd))
                           (unless @
                              (close Sock)
                              (off Sock) ) ) ) ) ) ) ) )
      '(localhost localhost)
      '(4041 4042)
      (40 80) ) )

And then with *ext* I need to create that single look ahead queue in the
local code you talked about earlier, but how?

I mean at the moment the problem is that I get too many articles in my local
code since all the remotes send all their articles at once, thus swamping
the local process, I'll show you what I'm using now:

(dm evalAll> @
   (let Result
         (for N (getMachine> This "localhost")
            (later (chain (cons "void"))
               (eval> This N (rest)))))
      (wait 5000 (not (memq "void" Result)))

(Note that this logic does not respect a multi machine environment, I will
add that when/if my current single machine is not enough.)

This one will evalute code on all remotes and return all the results. If the
result contains let's say more than 10 000 articles I will choke as it is
now. That's why I need that single look ahead you talked about, but I don't
know how to implement it.

If it was just about returning the 25 newest articles I could have each
remote simply return the 25 newest ones and then sort again locally. In that
case I would get 50 back and not 10 000 in this case. And when I want the
next result which will be 25-50 I suppose I could return 50 from each remote
then but this is a very ugly solution that doesn't scale very well.

On Sun, Apr 25, 2010 at 12:05 PM, Alexander Burger <>wrote:

> Hi Henrik,
> > I've reviewed the **Ext* part in the manual and I will need something
> > different as I will have several nodes on each machine on different ports
> > (starting with simply localhost). I suppose I could have simply modified
> it
> > if I had had one node per machine?
> With "node" you mean a server process? What makes you think that the
> example limits it to one node? IIRC, the example is in fact a simplified
> version (perhaps too simplified?) of a system where there were many
> servers, of equal and different types, on each host.
> > Anyway, what would the whole procedure you've described look like if I
> have
> > two external nodes listening on 4041 and 4042 respectively but on
> localhost
> > both of them, and the E/R in question looks like this?:
> >
> > (class +Article +Entity)
> > (rel aid       (+Key +Number))
> > (rel title     (+String))
> > (rel htmlUrl   (+Key +String)) #
> > (rel body      (+Blob))
> > (rel pubDate   (+Ref +Number))
> Side question: Is there a special reason why 'pubDate' is a '+Number'
> and not a '+Date'? Should work that way, though.
> > In this case I want to fetch article 25 - 50 sorted by pubDate from both
> > nodes
> Unfortunately, this cannot be achieved directly with an '+Aux' relation,
> because the article number and the date cannot be organized into a
> single index with a primary and secondary sorting criterion.
> There is no other way then fetching and then sorting them, I think:
>   (by '((This) (: pubDate)) sort (collect 'aid '+Article 25 50))
> Thus, the "send" part from a node to the central server would be
>   (for Article
>      (by
>         '((This) (: pubDate))
>         sort
>         (collect 'aid '+Article 25 50) )
>      (pr Article)         # Send the article object
>      (NIL (flush)) )      # Flush the socket
> The 'flush' is important, not so much to immediately send the data, but
> to detect whether the other side (the central server) has closed the
> connection, perhaps because it isn't interested in further data.
> 'flush' returns NIL if it cannot send the data successfully, and thus
> causes the 'for' loop to terminate.
> > So as far as I've understood it a (setq *Ext ... ) section is needed and
> > then the specific logic described in your previous post in the form of
> > something using *ext* or maybe *remote*?
> Yes. '*Ext' is necessary if remote objects are accessed locally.
> 'remote' might be handy if Pilog is used for remote queries. This is not
> the case in the above example.
> But 'ext' is needed on the central server, with the proper offsets for
> the clients. This can be all encapsulated in the +Agent objects.
> Cheers,
> - Alex
> --

Reply via email to