# Dealing with an asynchronous call, in a synchronized manner

**URL:** <https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326>\
**Category:** General\
**Created:** [March 2, 2023, 10:10am UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326 "2023-03-02T10:10:14Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2023, 10:10am UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/1 "2023-03-02T10:10:14Z")

</div>

Hello,

I am currently looking to interface a Prolog code with a peer system. The interaction is completely asynchronous via websockets.

During Prolog processing I want to query the state of an object within the peer system, and then continue continue processing with the state received.

Is there a way to pause prolog processing until an asynchronous interaction completes “under the hood”.

E.g.

```prolog
goal(X) :- 
    async_process( X, y_object, Y) ,
    process(X, Y).

```

Internally, async\_process(X, y\_object, Y) looks to do the following:

1. send a websocket message to a peer requesting the value of a y\_object using some unique request identifier.
2. the message is received by the peer which responds with a websocket message that includes the value of y\_object
3. in prolog that message is received with the identifier, and thereby matched with the prior request for Y
4. Y is bound – somehow to the received value

Step 4 – is unclear to me – can it be done?

Or does this need to be architected differently – ie. goal1 above has to be made into two parts – one that causes the message to be sent, and another part that is called upon response.

Something like this:

```prolog
goal(X) :-
       async_process( X, y_object, Y, call_back(goal_call_back)) .

goal_call_back(X,Y) :-
     process(X,Y).

```

thanks,

Dan

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 2, 2023, 10:51am UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/2 "2023-03-02T10:51:04Z")

</div>

The best I can think of for async\_process is something like this:

```prolog
async_process(X,y_object,Y) :-
     request(X,y_object),
     thread_get_message(reply(Y)).

```

And some service watching for replies, using some additional logic based on the identifier to find the waiting thread and do `thread_send_message(TID, reply(Value))`.

You can also go the now popular ( 🙂 ) fiber route, run the code in an engine and yield from it after sending the request. The main scheduler will find the reply, identify the engine waiting for it and resume this engine with the reply.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2023, 11:27am UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/3 "2023-03-02T11:27:59Z")

</div>

Thank you, Jan.

Since any solution will require dealing with asynchronicity, i am thinking to make the code “data” driven – i.e. to put more data into the payload, so that computations can be done a-contextually.

So, i will not need to deal with threads or engines directly.

Wonder how this will look like in the end 🙂

Dan

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2023, 5:30pm UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/4 "2023-03-02T17:30:38Z")

</div>

In the end, I implemented a session at the prolog side in order to reduce the payload to essentially an identifier (and a bit more).

Looks like thats a way to go

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2023, 10:19pm UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/7 "2023-03-02T22:19:38Z")

</div>

thanks,

i guess, the key saving is no need for an explicit callback.

but i would still need to hold / pass around accross websockets a session id linking to the thread id, probably in the dynamic db. And i guess no need to use call/2 to call back the call back.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 2, 2023, 10:37pm UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/8 "2023-03-02T22:37:54Z")

</div>

is it possible to post a value to a queue from outside prolog …

---

<div class="post-metadata">

**Author:** ![jan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jan/32/4_2.png) [@jan](https://swi-prolog.discourse.group/u/jan)\
**Post date:** [March 3, 2023, 7:59am UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/9 "2023-03-03T07:59:00Z")

</div>

You mean whether you can access Prolog message queues from C? Currently not. You’d need a call through Prolog.

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 4, 2023, 7:42pm UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/11 "2023-03-04T19:42:38Z")

</div>

Hi Jan

My call back based solution ran into asyc problems – when I need to aggregate results – waiting on the results is a problem with all the asychronous “half” websocket calls happening between peers.

I want to try your idea "thread\_get\_message(reply(Y)) …

But, the problem has a bit changed.

I need to generate a varying number of websocket asynchronous calls (based on a foreach generator), each generating a websocket asynchronous “reply” call – (probably) each in a different thread.

I need thread\_get\_message(reply(Y) to wait until all websocket reply calls have completed – either all successfully, or at least one failed.

I wonder how this is set up – also perhaps thread wait is an option here … each async call adds something to a session (implemented in a module) and the goal in thead wait counts the number of results to see if all arrived.

hope i am making sense, in my description

Dan

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 4, 2023, 8:02pm UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/12 "2023-03-04T20:02:16Z")

</div>

actually, perhaps its simple.

I don’t (yet) have a requirement to run all generated computes in parallel - so i can “serialize” each reply – so, your solution should work

---

<div class="post-metadata">

**Author:** ![grossdan](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/grossdan/32/23_2.png) [@grossdan](https://swi-prolog.discourse.group/u/grossdan)\
**Post date:** [March 6, 2023, 10:03pm UTC](https://swi-prolog.discourse.group/t/dealing-with-an-asynchronous-call-in-a-synchronized-manner/6326/13 "2023-03-06T22:03:34Z")

</div>

@jan

First, your suggested pattern works great – in particular when wrapping the thread\_get\_message into a goal within another module – makes the code really clean.

But, I ran into a problem when trying to use transactions.

Basically, a transaction would wrap the whole code, including the async\_process/.3 and if the overall code fails in the end, there should be a rollback.

But, currently, when wrapped into a transaction, the code stops processing – i.e. freezes the debugger and nothing happens without debugger.

Can this be made to work - or are there too many threaded calls interneaved that make the mechanism hang up.

thanks,

Dan
