Re: [Pengines] Asynchronous rpc? (instead of pengine_rpc)

Luca Violanti <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <CAApdSwTpBrVsTjSSnXK+3UWVKznBrxX=CtkJEfMnffNOLdD47g@mail.gmail.com>
Hi,

what I am trying to achieve is a completely distributed, parallel execution.


test :-
    pengine_create([
        id(ID1),
        server('http://server1.org'),
        src_text("b(X) :- a(X). a(1).")
    ]),
    pengine_create([
        id(ID2),
        server('http://server2.org'),
        src_text("b(X) :- a(X). a(X) :- b(X).")
    ]),
    pengine_create([
        id(ID3),
        server('http://server3.org'),
        src_text("b(X) :- a(X). b(3).")
    ]),
    pengine_event_loop(handler, []).

handler(create(ID, _)) :-
    pengine_ask(ID, b(_), []).

handler(success(ID, X, false)) :-
    writeln(X),
    pengine_destroy(ID).

handler(success(ID, X, true)) :-
    writeln(X),
    pengine_next(ID, []).

handler(failure(ID)) :-
    writeln("Failure"),
    pengine_destroy(ID).

The code above, when executed by the caller, hangs before writing anything
because pengine_ask/3 is synchronous and makes the caller wait for the
result (the infinite loop on server2 is just a substitute for an
arbitrarily long code to be executed by one of the servers).
This makes the code not parallel at all!

What I'm looking for is something to "trigger" separate queries on
different servers without waiting between calls: if there was something
like that, the caller could write

[b(1)]
[b(3)]

as soon as the servers 1 and 3 ended their query.

Can this be done using, for example, more basic predicates like
pengine_send?


On 12 March 2014 16:02, Torbjörn Lager <[email protected]> wrote:

> Hello Luca,
>
> It is true that if you run
>
> ?- pengine_rpc('http://pengines.org', foo(X)), member(X, [1, 2, 3]).
>
> member(X, [1, 2, 3]) will not be called until
> pengine_rpc('http://pengines.org', foo(X)) returns with a solution to
> foo(X).
>
> If you want to run foo(X) asynchronously you need to use
> pengine_create/1, pengine_ask/3, and pengine_event_loop/2. This is
> somewhat sketchy, but here's what you can do:
>
> test :-
>     pengine_create([
>         server('http://server1.org')
>     ]),
>     pengine_event_loop(handler, []).
>
>
> handler(create(ID, _)) :-
>     % The pengine is running and is waiting for input
>     % Let's send it a query
>     pengine_ask(ID, foo(X), []).
>
> handler(success(ID, foo(X), _)) :-
>     % X is now bound; do what you want here,
>     % e.g. ask for the next solution
>     pengine_next(ID, []).
>
> More handlers here...
>
>
> Note that pengine_event_loop/2 will still block though. It will do so
> until it receives destroy events from all pengines that it has
> initially received create events from (in this case only one).
>
> You can also do this:
>
> test :-
>     pengine_create([
>         server('http://server1.org')
>     ]),
>     pengine_create([
>         server('http://server2.org')
>     ]),
>     pengine_event_loop(handler, []).
>
>
> Here, the two pengines are running completely independently of each
> other. The pengine_event_loop can be thought of as a "controller" -
> this is where you decide what to do next based on what hits the
> handlers. In order to determine from which process a particular event
> is coming from, you may need to pass the IDs to the handler, like so:
>
> test :-
>     pengine_create([
>         id(ID1),
>         server('http://server1.org')
>     ]),
>     pengine_create([
>         id(ID2),
>         server('http://server2.org')
>     ]),
>     pengine_event_loop(handler(ID1, ID2), []).
>
>
> and then of course handler/1 will have to be handler/3.
>
> In the NEXT version of library(pengines) you won't have to wait for
> the create event, and will be able to write
>
> test :-
>     pengine_create([
>         id(Server1),
>         server('http://server1.org'),
>         ask(foo(X))
>     ]),
>     pengine_create([
>         id(Server2),
>         server('http://server2.org'),
>         ask(bar(X))
>     ]),
>     pengine_event_loop(handler(Server1, Server2), []).
>
>
> Hope this helps!
>
> Best regards,
> Torbjörn
>
> On Wed, Mar 12, 2014 at 12:04 PM, Luca Violanti <[email protected]>
> wrote:
> > Hi all,
> > I am experimenting with pengines as I am implementing a distributed
> theorem
> > prover for some extensions of Description Logics.
> > At the moment, the theorem prover works as a single threaded program in 2
> > phases.
> >
> > Current implementation's workflow example:
> > P1 runs...
> > P1 finds a checkpoint
> > P1 invokes P2 locally and waits
> > --- P2 runs
> > --- ...
> > --- P2 ends - control returns to P1
> > P1 runs... etc.
> >
> > The idea is to develop it so that it can run on a distributed
> architecture:
> > one "client" program which runs the first phase, then, each time it finds
> > some intermediate results, it invokes a second phase check on a separate
> > "server", asynchronously.
> >
> > Client                         Server 1                 Server 2
> >
> > P1 runs...
> > P1 finds a checkpoint
> > P1 invokes P2 on Server 1 ---> P2 runs independently
> > P1 keeps running...            ...
> > P1 finds a checkpoint          ...
> > P1 invokes P2 on Server 2 ----------------------------> P2 runs
> > independently
> > P1 keeps running...            ...                      ...
> > etc.
> >
> > To keep things simple, the servers can assert a "finished" fact and then
> > the Client can do some polling to retreive the results.
> > This way all the servers just have to be listening, do their job when
> asked
> > to, and they don't need to send anything back to the client.
> >
> >
> > I have played a bit with the client/server example found in the examples
> > folder (pl-7.1.9/packages/pengines/examples), which seems quite suitable
> > for my needs.
> > The only obstacle is that I need a way to do an asynchronous rpc, while
> the
> > pengine_rpc implementation seems to be locking.
> > Is there a way for my client to send predicates to a server without
> waiting
> > for their response?
> >
> > Any ideas?
> >
> > Thank you,
> > --
> > Luca Violanti
> > -------------- next part --------------
> > HTML attachment scrubbed and removed
> > _______________________________________________
> > SWI-Prolog mailing list
> > [email protected]
> > https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prolog
>
>
>
> --
> Torbjörn Lager
> Professor of General and Computational Linguistics
> Department of Philosophy, Linguistics and Theory of Science
> University of Gothenburg
> Box 200, SE-405 30 Gothenburg, Sweden
> Phone: +46317864962
>



-- 
Luca Violanti - desperatenerd.wordpress.com
There are only 10 types of people in the world: those who understand
ternary, those who don't, and those who mistake it for binary
-------------- next part --------------
HTML attachment scrubbed and removed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.