atlas-engineer / cl-electron

Lisp Interface to Electron.
BSD 3-Clause "New" or "Revised" License
16 stars 1 forks source link

Handle on-event for web-contents #21

Closed jmercouris closed 7 months ago

jmercouris commented 7 months ago

This allows for execution of arbitrary Lisp on arbitrary events within the JavaScript side.

During this implementation I realized that the client.on('data... for all events may be called.

How did I realize this?

I noticed that when we have a return value via our on-event callback, dispatch-callback was writing back to the JavaScript side. This resulted in our method in protocol.lisp being invoked:

"(request) => {
    return new Promise((resolve, reject) => {
        jsonString = JSON.stringify({ callback: ~a, request: request.url });
        client.write(`${jsonString}\\n`);
        let message_buffer = '';
        client.on('data', data => {
            let data_string = data.toString();
            let transmission_end_index = data_string.indexOf('');
            if (transmission_end_index == -1) {
                message_buffer += data_string;
            } else {
                message_buffer += data_string.substring(0, transmission_end_index);
                const jsonObject = JSON.parse(message_buffer);
                message_buffer = data_string.substring(transmission_end_index + 1, data_string.length)
                if (jsonObject.callback == ~a) {
                   const newResponse = new Response(jsonObject.dataString, {
                     headers: { 'content-type': jsonObject.dataType }
                   });
                   resolve(newResponse);
                }
            }
        });
    });
}

We were getting a client.on('data... which makes sense. Lisp was writing data using this same socket connection. However we did not want it to be consumed by this particular client.on('data.... We perhaps wanted it to be consumed by another client.on('data..., one dedicated to this event type/object.

Therefore I see two primary options.

  1. Implement a socket PER event type/object.
  2. Write a 'master' client.on('data... that does intelligent routing to the correct function (similar to what we do in Lisp via a hash table).

I will think about this and draft an implementation.

jmercouris commented 7 months ago

I will submit a follow-up pull request where I try to solve this problem, generally.

jmercouris commented 7 months ago

I am leaning towards solution 1. The reason is because our data is chunked, we don't have an easy way to associate a particular message with a particular recipient.

If we assume messages arrive in order, then the first part of our message could include the recipient ID, but can we assume that? I know we are using TCP, but we are also using multiple threads to send messages. I will think about it.

aadcg commented 7 months ago

Thanks for working on this. I understand the limitation of the current implementation. Let's keep this open for now.

jmercouris commented 7 months ago

I've fixed the generalized problem, and will now update this pull request to use the new technology.

jmercouris commented 7 months ago

Updated to use new technology! @aadcg !

aadcg commented 7 months ago

Will review soon, thanks.

aadcg commented 7 months ago

Let me review this PR carefully next Monday and then I'll merge it, thanks.

aadcg commented 7 months ago

Thanks @jmercouris.