bug#38807: [Feature request]: Support lisp workers like web workers.

classic Classic list List threaded Threaded
67 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
I think the web worker is a good design for GUI applications such as web browser. The workers do heavy work and provide the results to the UI thread. The UI thread only displays the result and responds to user input events which makes good user responsiveness.

The web workers run in other context. They can’t access data in the UI thread. They can only communicate with the UI thread by calling some limited APIs.


Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Eli Zaretskii
> Date: Mon, 30 Dec 2019 13:27:44 +0800
> From: HaiJun Zhang <[hidden email]>
>
> I think the web worker is a good design for GUI applications such as web browser. The workers do heavy
> work and provide the results to the UI thread. The UI thread only displays the result and responds to user
> input events which makes good user responsiveness.
>
> The web workers run in other context. They can’t access data in the UI thread. They can only communicate
> with the UI thread by calling some limited APIs.

We have threads in Emacs, so you could start by using them, no?



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Dmitry Gutov
On 30.12.2019 17:23, Eli Zaretskii wrote:
> We have threads in Emacs, so you could start by using them, no?

The main point of Web Workers is that they run in parallel to the main
thread.

So the bit about not being able to access "data in the UI thread" is
about no need for synchronization, I suppose.



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Eli Zaretskii
> Cc: [hidden email]
> From: Dmitry Gutov <[hidden email]>
> Date: Mon, 30 Dec 2019 18:40:49 +0300
>
> On 30.12.2019 17:23, Eli Zaretskii wrote:
> > We have threads in Emacs, so you could start by using them, no?
>
> The main point of Web Workers is that they run in parallel to the main
> thread.

This reminds me of an old joke: when a shop owner was approached by an
employee asking to work 5 days a week, the owner answered: let's start
with one, and then gradually arrive at 5.

More to the point, I did say "you could start", didn't I?



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Michael Albinus
In reply to this post by Eli Zaretskii
Eli Zaretskii <[hidden email]> writes:

>> Date: Mon, 30 Dec 2019 13:27:44 +0800
>> From: HaiJun Zhang <[hidden email]>
>>
>> I think the web worker is a good design for GUI applications such as
>> web browser. The workers do heavy
>> work and provide the results to the UI thread. The UI thread only
>> displays the result and responds to user
>> input events which makes good user responsiveness.
>>
>> The web workers run in other context. They can’t access data in the
>> UI thread. They can only communicate
>> with the UI thread by calling some limited APIs.
>
> We have threads in Emacs, so you could start by using them, no?

The point seems to be that there is a dedicated UI thread. That we don't
have (yet) in Emacs, and I like this idea.

Best regards, Michael.



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Eli Zaretskii
> From: Michael Albinus <[hidden email]>
> Cc: HaiJun Zhang <[hidden email]>,  [hidden email]
> Date: Mon, 30 Dec 2019 19:31:26 +0100
>
> The point seems to be that there is a dedicated UI thread. That we don't
> have (yet) in Emacs, and I like this idea.

We do have that on MS-Windows.  Except that you'll be surprised how
much of "UI" in Emacs cannot be done in a separate thread, mainly
because the Lisp machine is under such complete control of what the UI
does, and you cannot run several instances of the Lisp machine
simultaneously and asynchronously.



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Eli Zaretskii
> Date: Mon, 30 Dec 2019 21:19:50 +0200
> From: Eli Zaretskii <[hidden email]>
> Cc: [hidden email], [hidden email]
>
> because the Lisp machine is under such complete control of what the UI
> does

This might confuse.  What I meant is that the Lisp machine controls a
lot of what the UI does, not the other way around (of course).



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
In reply to this post by Eli Zaretskii
在 2019年12月31日 +0800 AM3:19,Eli Zaretskii <[hidden email]>,写道:
From: Michael Albinus <[hidden email]>
Cc: HaiJun Zhang <[hidden email]>, [hidden email]
Date: Mon, 30 Dec 2019 19:31:26 +0100

The point seems to be that there is a dedicated UI thread. That we don't
have (yet) in Emacs, and I like this idea.

We do have that on MS-Windows. Except that you'll be surprised how
much of "UI" in Emacs cannot be done in a separate thread, mainly
because the Lisp machine is under such complete control of what the UI
does, and you cannot run several instances of the Lisp machine
simultaneously and asynchronously. 

What about the following idea:
1. Make the current lisp machine be customized which has two profiles:
    + full featured: as the current running lisp machine in emacs
    + subset one: without all UI functions
2. Run the full featured one as emacs does now. It acts as the master lisp machine(for UI only), which behave like the UI thread(process) in the web browser.
3. Run some subset ones for workers. Workers are started by the master lisp machine. Workers can send messages to the master machine by calling some APIs. The messages are copied to the master lisp machine, so GCs don’t need to work across machines.
4. Provide some APIs for them to communicate with each other.

Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

arthur miller
Cool idea.

I have a question.  Is it even necessary for lisp machine to control UI?

Couldn't lisp machine post its "ui events" to a some kind of render queue and maybe input queue, instead of drawing and handling stuff immediately in an OS window? That could decouple drawing from the rest and could open for some other interesting stuff when it comes for rendering. 

I don't know maybe another thread for input queue. Probably too much work and I really don't know if that would be possible with Emacs architecture, at least as of current. 

I mean does lisp machine really need to know where it draws? It could as well just "draw" some events to a queue which could be rendered away in different passes, by different threads and so on.

Skickat från min Samsung Galaxy-smartphone.



-------- Originalmeddelande --------
Från: HaiJun Zhang <[hidden email]>
Datum: 2019-12-31 01:42 (GMT+01:00)
Till: Michael Albinus <[hidden email]>, Eli Zaretskii <[hidden email]>
Ämne: bug#38807: [Feature request]: Support lisp workers like web workers.

在 2019年12月31日 +0800 AM3:19,Eli Zaretskii <[hidden email]>,写道:
From: Michael Albinus <[hidden email]>
Cc: HaiJun Zhang <[hidden email]>, [hidden email]
Date: Mon, 30 Dec 2019 19:31:26 +0100

The point seems to be that there is a dedicated UI thread. That we don't
have (yet) in Emacs, and I like this idea.

We do have that on MS-Windows. Except that you'll be surprised how
much of "UI" in Emacs cannot be done in a separate thread, mainly
because the Lisp machine is under such complete control of what the UI
does, and you cannot run several instances of the Lisp machine
simultaneously and asynchronously. 

What about the following idea:
1. Make the current lisp machine be customized which has two profiles:
    + full featured: as the current running lisp machine in emacs
    + subset one: without all UI functions
2. Run the full featured one as emacs does now. It acts as the master lisp machine(for UI only), which behave like the UI thread(process) in the web browser.
3. Run some subset ones for workers. Workers are started by the master lisp machine. Workers can send messages to the master machine by calling some APIs. The messages are copied to the master lisp machine, so GCs don’t need to work across machines.
4. Provide some APIs for them to communicate with each other.

Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Eli Zaretskii
In reply to this post by HaiJun Zhang
> Date: Tue, 31 Dec 2019 08:40:06 +0800
> From: HaiJun Zhang <[hidden email]>
> Cc: [hidden email]
>
>  We do have that on MS-Windows. Except that you'll be surprised how
>  much of "UI" in Emacs cannot be done in a separate thread, mainly
>  because the Lisp machine is under such complete control of what the UI
>  does, and you cannot run several instances of the Lisp machine
>  simultaneously and asynchronously.
>
> What about the following idea:
> 1. Make the current lisp machine be customized which has two profiles:
>     + full featured: as the current running lisp machine in emacs
>     + subset one: without all UI functions
> 2. Run the full featured one as emacs does now. It acts as the master lisp machine(for UI only), which behave
> like the UI thread(process) in the web browser.
> 3. Run some subset ones for workers. Workers are started by the master lisp machine. Workers can send
> messages to the master machine by calling some APIs. The messages are copied to the master lisp
> machine, so GCs don’t need to work across machines.
> 4. Provide some APIs for them to communicate with each other.

The Lisp interpreter already sort-of "queues" display changes, because
it only changes Lisp data structures, and then the display engine
references those data structures at display time.  So those data
structures serve as a kind-of "queue", since redisplay runs when Emacs
is idle (i.e., the last Lisp command completed its job).

But the problem is in the other direction: it's not that Lisp somehow
"drives" the UI, it's that the UI frequently calls into Lisp as part
of its job.  The simplest example is mode-line format: it includes
references to variables, and can also include :eval forms that call
the interpreter.

Your idea in fact means to have several isolated Lisp machines in the
same process.  But how can we do something like that without a very
radical redesign of Emacs, when so many things in Emacs are implicitly
part of the global state?  Buffers, global variables, windows,
frames--all those are global resources, and every thread will want to
access them.  Emacs was not designed to allow that.

Your idea can be implemented with two processes, though.  And there is
already a package called emacs-async which does that:

  https://github.com/jwiegley/emacs-async

The disadvantage is that it is cumbersome to share data between the
two instances of Emacs, and large amounts of data will make that
inefficient.



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
在 2020年1月1日 +0800 AM12:36,Eli Zaretskii <[hidden email]>,写道:
The Lisp interpreter already sort-of "queues" display changes, because
it only changes Lisp data structures, and then the display engine
references those data structures at display time. So those data
structures serve as a kind-of "queue", since redisplay runs when Emacs
is idle (i.e., the last Lisp command completed its job).

But the problem is in the other direction: it's not that Lisp somehow
"drives" the UI, it's that the UI frequently calls into Lisp as part
of its job. The simplest example is mode-line format: it includes
references to variables, and can also include :eval forms that call
the interpreter.


It is much clearer to me now. We can keep them all as the UI thread.

Your idea in fact means to have several isolated Lisp machines in the
same process. But how can we do something like that without a very
radical redesign of Emacs, when so many things in Emacs are implicitly
part of the global state? Buffers, global variables, windows,
frames--all those are global resources, and every thread will want to
access them. Emacs was not designed to allow that.


All those global resources are not accessible by workers. Workers can only access network, file system and other non-global resources. They only do the following things:
1. retrieve content from network, parse the data, and send the result(lisp data) to the UI thread to present it
2. communicate with subprocesses, parse the data from subprocesses, and send the result to the UI thread
3. do file indexing and send the index result to the UI thread
4. do other heavy work like mathematicl calculation and deep learning, send the result to the UI thread

Let the UI thread do as less work as possible.


Your idea can be implemented with two processes, though. And there is
already a package called emacs-async which does that:

https://github.com/jwiegley/emacs-async


I knew this package. It is a good idea. Modern web browsers also use separate processes to render page content(one or more pages per process). They design specific IPC to let the worker processes to communicate with the main(UI) process. They have good performance and good user responsiveness. 

I think emacs is much like web browsers. Both render large text content and care user responsiveness. We can learn from them.

The disadvantage is that it is cumbersome to share data between the
two instances of Emacs, and large amounts of data will make that
inefficient. 

We may design an IPC for their communication.

Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
In reply to this post by Dmitry Gutov
在 2019年12月30日 +0800 PM11:40,Dmitry Gutov <[hidden email]>,写道:
On 30.12.2019 17:23, Eli Zaretskii wrote:
We have threads in Emacs, so you could start by using them, no?

The main point of Web Workers is that they run in parallel to the main
thread.

So the bit about not being able to access "data in the UI thread" is
about no need for synchronization, I suppose. 

Yes. That is what I mean. They can do heavy work without pausing user input.

Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
In reply to this post by Michael Albinus
在 2019年12月31日 +0800 AM2:31,Michael Albinus <[hidden email]>,写道:

The point seems to be that there is a dedicated UI thread. That we don't
have (yet) in Emacs, and I like this idea.


We can even keep all in emacs currently as the “UI thread”and run another lisp machine for a worker.

Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
In reply to this post by Eli Zaretskii
在 2019年12月31日 +0800 AM12:26,Eli Zaretskii <[hidden email]>,写道:
This reminds me of an old joke: when a shop owner was approached by an
employee asking to work 5 days a week, the owner answered: let's start
with one, and then gradually arrive at 5.

More to the point, I did say “you could start", didn't I? 

I can’t understand this. Can you explain it?
Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Eli Zaretskii
> Date: Wed, 1 Jan 2020 11:20:25 +0800
> From: HaiJun Zhang <[hidden email]>
> Cc: [hidden email]
>
> 在 2019年12月31日 +0800 AM12:26,Eli Zaretskii <[hidden email]>,写道:
>
>  This reminds me of an old joke: when a shop owner was approached by an
>  employee asking to work 5 days a week, the owner answered: let's start
>  with one, and then gradually arrive at 5.
>
>  More to the point, I did say “you could start", didn't I?
>
> I can’t understand this. Can you explain it?

Whatever application you have in mind, try implementing it using what
we already have regarding Lisp threads, and see if the limitations
Michael mentioned are really so grave.  It could be that for some
applications what we have is good enough.  And if not, you will
collect some experience and understand better what additional features
do you need.



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
In reply to this post by arthur miller
My understanding of the display flow:
1. an event comes which causes redisplay
2. the display engine prepares the glyph matrix
3. convert the glyph matrix to bitmap and display it

I think lots of work are in 2. During the work in 2, the display code needs to access many resources in lisp machine and even may eval lisp forms. The resources it accesses are too wildcard, so that we can't copy the resources to it and put them to queue. For multi-threading, we need a global lock.

在 2019年12月31日 +0800 AM9:39,arthur miller <[hidden email]>,写道:
Cool idea.

I have a question.  Is it even necessary for lisp machine to control UI?

Couldn't lisp machine post its "ui events" to a some kind of render queue and maybe input queue, instead of drawing and handling stuff immediately in an OS window? That could decouple drawing from the rest and could open for some other interesting stuff when it comes for rendering. 

I don't know maybe another thread for input queue. Probably too much work and I really don't know if that would be possible with Emacs architecture, at least as of current. 

I mean does lisp machine really need to know where it draws? It could as well just "draw" some events to a queue which could be rendered away in different passes, by different threads and so on.

Skickat från min Samsung Galaxy-smartphone.



-------- Originalmeddelande --------
Från: HaiJun Zhang <[hidden email]>
Datum: 2019-12-31 01:42 (GMT+01:00)
Till: Michael Albinus <[hidden email]>, Eli Zaretskii <[hidden email]>
Ämne: bug#38807: [Feature request]: Support lisp workers like web workers.

在 2019年12月31日 +0800 AM3:19,Eli Zaretskii <[hidden email]>,写道:
From: Michael Albinus <[hidden email]>
Cc: HaiJun Zhang <[hidden email]>, [hidden email]
Date: Mon, 30 Dec 2019 19:31:26 +0100

The point seems to be that there is a dedicated UI thread. That we don't
have (yet) in Emacs, and I like this idea.

We do have that on MS-Windows. Except that you'll be surprised how
much of "UI" in Emacs cannot be done in a separate thread, mainly
because the Lisp machine is under such complete control of what the UI
does, and you cannot run several instances of the Lisp machine
simultaneously and asynchronously. 

What about the following idea:
1. Make the current lisp machine be customized which has two profiles:
    + full featured: as the current running lisp machine in emacs
    + subset one: without all UI functions
2. Run the full featured one as emacs does now. It acts as the master lisp machine(for UI only), which behave like the UI thread(process) in the web browser.
3. Run some subset ones for workers. Workers are started by the master lisp machine. Workers can send messages to the master machine by calling some APIs. The messages are copied to the master lisp machine, so GCs don’t need to work across machines.
4. Provide some APIs for them to communicate with each other.

Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
In reply to this post by Eli Zaretskii
OK. I got it.
One example is lsp-mode for dart language. One completion result is 10000 lines. And emacs doesn’t respond for about 3~4s. This experience kept me away from lsp-mode for half a year.
在 2020年1月1日 +0800 AM11:37,Eli Zaretskii <[hidden email]>,写道:
Date: Wed, 1 Jan 2020 11:20:25 +0800
From: HaiJun Zhang <[hidden email]>
Cc: [hidden email]

在 2019年12月31日 +0800 AM12:26,Eli Zaretskii <[hidden email]>,写道:

This reminds me of an old joke: when a shop owner was approached by an
employee asking to work 5 days a week, the owner answered: let's start
with one, and then gradually arrive at 5.

More to the point, I did say “you could start", didn't I?

I can’t understand this. Can you explain it?

Whatever application you have in mind, try implementing it using what
we already have regarding Lisp threads, and see if the limitations
Michael mentioned are really so grave. It could be that for some
applications what we have is good enough. And if not, you will
collect some experience and understand better what additional features
do you need.
Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

HaiJun Zhang
In reply to this post by Eli Zaretskii
While with the same dart project, the VSCode has good user responsiveness. As far as I known, the extensions of VSCode runs in separate process.
在 2020年1月1日 +0800 AM11:57,HaiJun Zhang <[hidden email]>,写道:
OK. I got it.
One example is lsp-mode for dart language. One completion result is 10000 lines. And emacs doesn’t respond for about 3~4s. This experience kept me away from lsp-mode for half a year.
在 2020年1月1日 +0800 AM11:37,Eli Zaretskii <[hidden email]>,写道:
Date: Wed, 1 Jan 2020 11:20:25 +0800
From: HaiJun Zhang <[hidden email]>
Cc: [hidden email]

在 2019年12月31日 +0800 AM12:26,Eli Zaretskii <[hidden email]>,写道:

This reminds me of an old joke: when a shop owner was approached by an
employee asking to work 5 days a week, the owner answered: let's start
with one, and then gradually arrive at 5.

More to the point, I did say “you could start", didn't I?

I can’t understand this. Can you explain it?

Whatever application you have in mind, try implementing it using what
we already have regarding Lisp threads, and see if the limitations
Michael mentioned are really so grave. It could be that for some
applications what we have is good enough. And if not, you will
collect some experience and understand better what additional features
do you need.
Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

Michael Albinus
In reply to this post by HaiJun Zhang
HaiJun Zhang <[hidden email]> writes:

>     The point seems to be that there is a dedicated UI thread. That we
>     don't
>     have (yet) in Emacs, and I like this idea.
>
> We can even keep all in emacs currently as the “UI thread”and run
> another lisp machine for a worker.

I'm not expecting to get a UI thread with all glories it is specified
for web workers. I would already be happy if we could find a solution
for supporting user input in a threaded package, as it is discussed in
bug#25214 and bug#32426.

Best regards, Michael.



Reply | Threaded
Open this post in threaded view
|

bug#38807: [Feature request]: Support lisp workers like web workers.

arthur miller
In reply to this post by HaiJun Zhang


-------- Originalmeddelande --------
Från: HaiJun Zhang <[hidden email]>
Datum: 2020-01-01 04:17 (GMT+01:00)
Till: Eli Zaretskii <[hidden email]>, Michael Albinus <[hidden email]>
Ämne: bug#38807: [Feature request]: Support lisp workers like web workers.

在 2019年12月31日 +0800 AM2:31,Michael Albinus <[hidden email]>,写道:

The point seems to be that there is a dedicated UI thread. That we don't
have (yet) in Emacs, and I like this idea.


> We can even keep all in emacs currently as 
> the “UI thread”and run another lisp machine > for a worker.

Isn't emasc-server/emacsclient already already that?
1234