kdb+k

On parallel execution - which side reports about an error?


When using different methods (sync/async) to callback a caller process I'm getting an error on different sides:

$ q -p 1234  │$ q
             │q)h:hopen`::1234;
             │q)neg[h]({.z.w x};42)
q)'type      │
             │q)neg[h]({neg[.z.w] x};42)
             │q)'type
             │
             │q)neg[h]({neg[.z.w] x};42); h[]
             │42

Could you explain this behavior for 1st and 2nd cases please? Why does an exception raize on the 2nd process with the sync callback command .z.w x, and on the caller with the neg[.z.w] callback?

And for the 3rd case: is this something like a pattern (or common use case in IPC) to chase async calls with 'sync' handles with empty args h[]/h(::) to get the results back making such ad-hock handlers for them?


Upd: Does blocking receive construct replaces .z.ps/.z.pg calls?


Upd2: If there exists deferred synchronous - is there something like deferred asynchronous?


Asked about Upd and Upd2 here.


Solution

  • The below should help clarify on what's happening

    case 1: This gives the appearance of failing on the remote but it's not. It's being evaluated on the remote to '.z.w 42' which sends a sync message back to the local process, where it's evaluated by .z.pg (whose default definition is value). 'value 42' results in a type error which is returned to the remote.

    q)h:hopen 1234
    q).z.pg:{value x};system"e 1"
    q)neg[h]({.z.w x};42)
    q)'type
      [0]  .z.pg:{value x}
                  ^
    q))
    

    case 2: again the evaluation of 'value 42' (this time by .z.ps - whose default definition is also value) fails with a type error but as it's async it's not returned to the sending process

    q).z.ps:{value x}
    q)
    q)neg[h]({neg[.z.w] x};42)
    q)'type
      [0]  .z.ps:{value x}
                  ^
    q))
    

    case 3: This is a method of IPC communication known as deferred synchronous. We block/listen/hang on the connection after sending the async message, awaiting a response, using a construct known as a blocking receive

    q)neg[h]({neg[.z.w] x};42);h[]
    42
    

    In some cases it may not be necessary to hang on the connection i.e. if the callback invokes another function like so

    q)neg[h]({neg[.z.w](0N!;x)};42);
    q)42
    
    q)add:(0N!10+);neg[h]({neg[.z.w](`add;x)};42);
    q)52
    

    Deferred synchronous messaging is used in mserve.q here - https://github.com/KxSystems/kdb/blob/master/e/mserve.q