Any chance a dev(Bram, Ben Fritz, ZyX..) could comment? Heres the feedback I was
hoping for:
- Was I not clear about something?
- Are my assumptions valid? If not, what did I miss?
- Theres any chance I could get help? As stated in the main post, I had a few
troubles which I believe could be easily solved with the help of a developer
with more experience in hacking the code
- Is there any hope something like this will ever be merged? This is the most
important feedback because it will give me a clue on whether I should continue
to work on the patch.
It maybe needs, but it is not a problem introduced by this patch: I used to deal with hangs due to powerline threads long before this patch and the best solutions we came up with are:
1. Use daemon threads. This means thread can be interrupted at exit in virtually any state which may be a problem in some use cases.
2. As our threads were mostly waiting we used an threading.Event instance to wait and not time.sleep. I.e. thread is either wakened by triggered event in which case it exits or it is wakened after specified timeout in which case it does its job.
There are no standard ways to forcefully interrupt threads in Python so any program (plugin in our case) willing to use threads must write its own shutdown handlers. If I am not mistaking it is some design decision made on purpose.
> Best,
> Christian
> --
I really like this approach and hope Bram will consider this some day. Just wanted to say: Keep up the good work!
I am not hopeful for this patch, but I would love to see you succeed. We spent around two months working on adding async support to Vim without threads, https://groups.google.com/d/msg/vim_dev/-4pqDJfHCsM/LkYNCpZjQ70J . We added a timer function and called the callbacks in the main loop when appropriate. Ultimately, we gave up for a few reasons:
1. A large percent of the Vim community was outright hostile to the idea.
2. Bram was disinterested
3. Vim was unstable with the patch (segfaults outside of the patched code) AND
4. The Vim code base is abysmal.
How stable is this patch and what do you think about cross platform support?
-Matt
I don't remember that at all! I think a lot of people liked the idea in general, but didn't like the idea of an uninterruptable task that would potentially take over Vim every 100 milliseconds or something. I think you were well on the way to fixing that.
There was pretty universal dislike for the idea of any "official" runtime plugin using the timed events, I think. People like their "out of the box" Vim to be very predictable.
> 2. Bram was disinterested
If I recall, Bram wanted to see tests. And the crashes fixed.
> 3. Vim was unstable with the patch (segfaults outside of the patched code) AND
> 4. The Vim code base is abysmal.
>
Yeah that's a problem, and the complexity of the patch made it hard to solve. So for this sort of thing, simpler is probably better, even if not as fully featured.
Thiago,
It would be rather trivial for us to push timeout events into the queue as you suggested- our code already does this, but from a slightly different place than you hooked. I believe the last bug that stopped us was in memfile.c (which hasn't been touched in a decade) with a memory corruption error. In our experience, Vim is only robust in so much as you don't step outside of the normal flow which makes me suspicious you will run into the same problems. I'm guessing that CursorHold and friends may also need work. At any rate, I'll have a look at your patch and try to get the Floobits python plugin to work on top of it.
-Matt
I would love this to work and I thank you for your effort, but I'm quite doubtful that vgetc can be safely run in a background thread. It simply does too much work. Just to pick one example, it appears to be responsible for blinking the GUI cursor while it's waiting, which will obviously conflict with any screen updates the main thread is doing. I've built your fork with TSan[1] enabled and run snake.vim and it complains of many other race conditions. I can send you the log if you're interested but I would suggest using TSan yourself.
Best,
Ash
[1] TSan: http://code.google.com/p/thread-sanitizer
I thought the idea of this patch, was to allow background threads to send Vim a message, that says "when you get a chance, run function X". Then, at some later point in time, when Vim is not busy, it will run function X *IN THE MAIN THREAD*. Thus there should be no conflict between the deferred function and the main thread. Am I correct in this?
If so, plugin authors must simply ensure that function X is threadsafe with the background functions in the same thread. This probably means making sure that the background thread is DONE with whatever data function X will access, until function X can run and is done with that data.
So, your background thread is directly calling a function to get user input/update the screen? I think THAT is a mistake. This should not happen. A background thread can be used for data processing, but any user input, buffer changes, screen updates, etc. should ALWAYS be handled in the main thread, possibly in a deferred function. A background thread should ALWAYS be able to have the main thread interrupt it. Calling functions in the background which remove things from Vim's input queue or redraw the screen is begging for trouble. I thought that was the point of the deferred functions, to allow all such things to happen in the foreground thread. If you allow calling any arbitrary Vim function in a background thread, then we would need to make every arbitrary Vim function thread-safe, and this project becomes huge to the point of being unmanageable.
I think the "deferred function executed in the main thread" is a clever idea, but to use it the background thread can only access data that the foreground thread will not be accessing, except in the deferred function designed for it. Redrawing the screen, getting user input, or whatever all need to happen in the foreground thread ONLY. If you need to change text or redraw the screen, call a deferred function to do it.
Hey guys, I hope I'm not late for this conversation.
I've implemented a method to call deferred functions in the main thread from a another thread (I'm using python's threading library for that). It works by spawning another instance of vim from the thread to send a command to the current instance (i.e. vim --servername <this instance's servername> --remote-expr <function to call>) so main thread ends up calling the specified function when it gets the chance.
Now, before you burn me alive, I now there's a lot of unnecessary overhead in this method ("spawning another Vim? Are you insane!?") but it's working surprisingly well for the use cases I have, i.e. it's all transparent for the user and I can't notice any performance hits.
My point is that I suspect (with high levels of confidence) that this same mechanism could be leveraged but without having to spawn a separate vim instance. This would require minimal source changes and it should just work because it would use the same mechanisms that are already working rock solid.
Let me know what do you think.
Not when it gets the chance. Check out the following: make server run `while 1 | sleep 1 | endwhile` and send that expression (I tested it on `input("abc")`). You will see that despite something being run received expression will still be processed. Though I am unable to reproduce this I remember @MarcWeber complaining about random crashes when using this feature on daily basis. Not too likely but still happening.
That was unexpected. I'll take a look into Vim's code just out of curiosity to see how these remote calls are being handled. I guess I have to wait for a robust solution to this problem but in the meantime I'll work with this solution and hope the odds favor me.
Thanks for pointing that out ZyX, please let me know if you find a way to make this work.