Closed Shadowfiend closed 11 years ago
Did you look at ViBufferedStream and NSTask-streaming? It's an async stream that works from Nu too.
See the ack bundle for an example of how to use it.
I'll have a look at those over the next couple of days, thanks!
First up, worth noting is that communication with ensime is over a socket, not over standard IO. So the issue here is that ViBufferedStream requires input/output file descriptors; in and of itself this isn't a big deal: we could write an initializer similar to initWithTask:
that takes an NSURL
instead and does its own socket management, but it seems like that would be ugly. I looked around to see if there's any way to get a read/write file handle to a socket from a Cocoa object the way we get read/write file handles from NSPipe
, but sadly it looks like you can only either get an NSFileHandle
, which doesn't provide access to the underlying descriptors, or you have to use NSStream getStreamsToHost:port:inputStream:outputStream:
, which only lets you interface using NSInputStream
and NSOutputStream
.
Given that there is already a Cocoa-wrapped solution that takes care of low-level socket management, I tend to think that it's better to add these two functions to the stream classes so they can be used properly from Nu than re-implement the socket handling code in ViBufferedStream. What do you think?
The problem with NSStream
is that it's not completely asynchronous. ViBufferedStream
does buffering on write and never blocks the application. To do it with NSStream
you need a thread, and I'd like to avoid that complexity as long as possible.
The NSFileHandle
object does have a fileDescriptor
method that sounds like what's needed. If you initialize a ViBufferedStream
with the same file descriptor for read and write, it will handle it properly as a bidirectional socket, so it's not tied to pipes.
Have a look at pull request #21. I don't think it's too ugly.
However, I'm not saying we can't have both.
Interesting. I think on a high level it could be useful to have these on NSData, but I like the ViBufferedStream approach for its consistency—one way to deal with buffered streams across plugins.
I'll pull that branch into my fork and try moving the current state of vico-ensime to it; I'll let you know if there are any issues on the other pull request.
Given that ViBufferedStream works fine with #21, I don't really mind whether this is merged or not. I'll leave it up to you and whether you consider it an important enough general utility to have the NSData interfaces on these streams :)
writeData:(NSData ) lets us write NSData objects from Nu, while (NSData )readData lets us read NSData objects from Nu. This lets us use input and output streams from Nu, since otherwise they deal in raw byte arrays that we can't manipulate easily from there.
These are put in Nu categories; let me know if you'd like them moved elsewhere. I'm using them to write bindings to ensime for background Scala compile verification.