On Thursday, February 18, 2016 at 11:22:37 AM UTC+9, mattn wrote:
> On Monday, February 15, 2016 at 5:09:17 AM UTC+9, Bram Moolenaar wrote:
> > Marcin Szamotulski wrote:
> > 
> > > > > > > That's a really great feature.  I am trying to implemented a gulp 
> > > > > > > plugin
> > > > > > > (gulp is a node package used to build web apps) based on channels 
> > > > > > > and
> > > > > > > there are two things that I has a problem with:
> > > > > > 
> > > > > > Thanks for the feedback.  Keep in mind that the feature is still 
> > > > > > being
> > > > > > developed.  Some things may just be missing.  But there can also be 
> > > > > > bugs
> > > > > > and things that don't work for you, so feedback is useful anyway.
> > > > > 
> > > > > Yes I understand that, the idea is to contribute to the development in
> > > > > some fruitful way.
> > > > 
> > > > Note that the type of the channel handle has changed.  That mainly
> > > > matters for when checking whether ch_open() worked.
> > > > 
> > > > > > > 1) when I use `job_start()` to start a server in the background 
> > > > > > > and
> > > > > > > immediately after I call `ch_open()` to open channel to that 
> > > > > > > server I am
> > > > > > > always refused: `E896: read from channel: Connection refused`.
> > > > > > > 
> > > > > > > However, if I check `job_status` in between (which is what
> > > > > > > I should do anyway), then the following `ch_open` runs fine.  
> > > > > > > There is
> > > > > > > no way now to communicate from the job that started that what it 
> > > > > > > runs is
> > > > > > > ready to connect to.
> > > > > > 
> > > > > > It's normal for a process to have some initialization time before 
> > > > > > the
> > > > > > socket is ready for use.  This is implemented, it already existed 
> > > > > > for
> > > > > > netbeans.  Did you add a "waittime" argument?  The default is zero.
> > > > > 
> > > > > I just tried it:
> > > > > * adding waittime does not help
> > > > > * adding `sleep 1m` before calling `ch_open` solved the problem
> > > > > 
> > > > > Which is not what I'd expect.
> > > > 
> > > > I assume we need to treat that error as a temporary failure and retry.
> > > > There was a similar problem on Mac, where a 1 msec waittime did work.
> > > 
> > > `sleep 100m` is more reliable, with just 1m wait I am getting errors
> > > today,
> > 
> > Thus increasing the waittime does not help, but a short sleep between
> > starting the job and ch_open() helps?  I think we need to handle a
> > failing connect properly.  There is code from Netbeans, but it's waiting
> > too long.
> > 
> > > > > > > 2) when my server sends data back to vim only the first message is
> > > > > > > received.  This can be reproduced by the demoserver.py example.  
> > > > > > > Just
> > > > > > > double the lines in `ThreadedTCPRequestHandler.handle`:
> > > > > > >     print("sending {}".format(encoded))
> > > > > > >     self.request.sendall(encoded.encode('utf-8'))
> > > > > > >     print("sending {}".format(encoded))
> > > > > > >     self.request.sendall(encoded.encode('utf-8'))
> > > > > > > 
> > > > > > > And vim will only get the first message.  It would be nice if the 
> > > > > > > socket
> > > > > > > was reading until explicitly closed by the server.  It would be 
> > > > > > > useful
> > > > > > > for my case to send updates from the background process spawn by 
> > > > > > > the server
> > > > > > > that I wrote.
> > > > > > 
> > > > > > If you are using raw messages Vim has no clue where a message ends 
> > > > > > and
> > > > > > whether there is more coming.  Vim should get the second message, 
> > > > > > but
> > > > > > possibly only in the next read.  If it never arrives there can be a 
> > > > > > bug.
> > > > > > I just fixed one where raw messages were dropped when there is no
> > > > > > handler.
> > > > > 
> > > > > I am using the default `json` messages.  I found that this works fine,
> > > > > from the server:
> > > > > 
> > > > >     socket.write(JSON.stringify([0, ["ex", "call MyHandler('" + msg + 
> > > > > "')"]);
> > > > > 
> > > > > the problem with this approach is to encode msg properly so that it
> > > > > does not contain any `'` which would be misinterpreted by vim when
> > > > > evaluating the expression.
> > > > > 
> > > > > 
> > > > > > I just added the ch_logfile() function, that will be useful to find 
> > > > > > out
> > > > > > what is happening.
> > > > > 
> > > > > Great, I will try and check what is going on.
> > > 
> > > `ch_logfile` is very helpful.  I could see that when I attach a handler
> > > with `ch_sendexpr` it is invoked only once on a message that has the
> > > correct ID. I was sending from the server `[requestID, data]` and if
> > > `requestID` is greater than 0 the callback is invoked only once and this
> > > seems the intended behaviour of `may_invoke_callback` function in
> > > channel.c.  Reading the source I found that I should rather register the
> > > callback as a channel callback using `ch_open`.
> > 
> > Correct.
> > 
> > > I think that the user expects that the callback will be called on every
> > > message with that given `requestID`.  The problem might be when to
> > > un-register the callback.  One could for example to check for the
> > > returned value, if is is false or true and remove it when is it is true.
> > > I guess this is all about freeing the memory and leaving this up to
> > > a plugin author might not be a safe option, is that the reason for one
> > > time callbacks?
> > 
> > The IDs are used to match the response to the request.  There must not
> > be more than one response to the same request.  They are considered
> > duplicates and dropped.
> > 
> > I don't know what you are doing, but if you have multiple responses than
> > you should probably use the channel callback, not the request callback.
> > 
> > > The current implementation give the same expressive power, since I can
> > > change some state variable in which is then used by the channel level
> > > callback that will be invoked.  One just has to be careful to send non
> > > zero requestID to vim only once.
> > 
> > Correct.
> > 
> > > If you want to keep the current behaviour, I think the docs should
> > > explain this in some detail.  I can write a patch for that.
> > 
> > I already made changes to channel.txt.  I will add a remark now.  Please
> > re-read the help later when the changes have settled down.
> > 
> > > When my server crashes, with a `SyntaxError` or a `ReferenceError`
> > > and the socket is not properly closed, I have to kill vim with SIGTERM,
> > > since the cursor gets frozen. This is what `ch_log` reports:
> > > 
> > >     on 0: Opening channel
> > >     on 1: Opening channel
> > >     : Connecting to localhost port 3746ERR on 1: channel_select_check(): 
> > > Cannot read
> > >     RECV on 1: '"DETACH"
> > >     '
> > >     on 1: Closing channelERR on 0: channel_select_check(): Cannot read
> > >     RECV on 0: '"DETACH"
> > >     '
> > >     ERR on 0: channel_select_check(): Cannot read
> > 
> > Error handling is tricky.  Perhaps Vim hangs in channel_close()?
> > Would be good if you can use a debugger to connect to the hanging Vim
> > and see where it's stuck.
> 
> My optinion is:
> 
> 1. ch_readraw/ch_sendraw should block if callback is not specified
> 2. ch_readraw/ch_sendraw should return empty string if callback is specified

This is my suggestion.

https://gist.github.com/mattn/d6198b38d9b18edcb2aa

ch_readraw, ch_sendraw, ch_sendjson take arguments dict can be taken callback.
If callback is specified, those functions return empty string. And callback in 
later. If callback is not specified, those function will block while reading 
data.

Now below's script is working on windows.

----------------------------------
function! Callback(id, msg)
  echo a:msg
endfunction
let g:job = job_start("tail -f logfile")
let handle = job_getchannel(job)
call ch_readraw(handle, {"callback": "Callback"})
----------------------------------

- mattn
 

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui