grpc iOS stream, send only when GRXWriter.state is started? - ios

I'm using grpc in iOS with bidirectional streams.
For the stream that I write to, I subclassed GRXWriter and I'm writing to it from a background thread.
I want to be as quick as possible. However, I see that GRXWriter's status switches between started and paused, and I sometimes get an exception when I write to it during the paused state. I found that before writing, I have to wait for GRXWriter.state to become started. Is this really a requirement? Is GRXWriter only allowed to write when its state is started? It switches very often between started and paused, and this feels like it may be slowing me down.
Another issue with this state check is that my code looks ugly. Is there any other way that I can use bidirectional streams in a nicer way? In C# grpc, I just get a stream that I write freely to.
Edit: I guess the reason I'm asking is this: in my thread that writes to GRXWriter, I have a while loop that keeps checking whether state is started and does nothing if it is not. Is there a better way to do this rather than polling the state?

The GRXWriter pauses because the gRPC Core only accepts one write operation pending at a time. The next one has to wait until the first one completes. So the GRPCCall instance will block the writer until the previous write is completed, by modifying its state!
In terms of the exception, I am not sure why you are getting the problem. GRXWriter is more like an abstract class and it seems you did your own implementation by inheriting from it. If you really want to do so, it might be helpful to refer to GRXBufferedPipe, which is an internal implementation. In particular, if you want to avoid waiting in a loop for writing, writing again in the setter of GRXWriter's state should be a good option.

Related

How to cleanup streams in a dartvm application?

Please note that I am asking about a strictly dart only application this does not concern flutter in any means, dartvm refers to the dart virtual machine.
As far as I understand Dart's idea of reactive state is implemented through streams, the responsibility of handling the lifetime of a stream object is given to the programmer, at runtime one could manipulate the stream as they see fit according to what works for their design by adding to the stream; listening to it or disposing it.
My question is this, Is it necessary that I need to call the dispose() method of a stream before my application quits? If I do, how do I go about accomplishing that? Hooking into the VM state isn't well documented and using ProcessSignal listeners is not portable, If I don't, does the GC handle this case? What's the best practice in this case?
Dart streams do not have a dispose method. Therefore you don't need to call it.
But just to give a little more detail ...
Dart streams are many things. Or rather, streams are pretty simple, they're just a way to provide a connection between code which provides events and code which consumes events. After calling listen, the stream object is no longer part of the communication, events and pushback goes directly between the event source (possibly a StreamController) and the consumer (a StreamSubscription).
Event providers are many things.
Some events are triggered just by code doing things. There is no need to clean up after those, it's just Dart objects like everything else, and they will die with the program, and can be garbage collected earlier if no live code refers to them.
Some events are triggered by I/O operations on the underlying operating system. Those will usually be cleaned up when the program ends, because they are allocated through the Dart runtime system, and it knows how to stop them again.
It's still a good idea to cancel the subscription as soon as you don't need any more events. That way, you won't keep a file open too long and prevent another part of the program from overwriting it.
Some code might allocate other resources, not managed by the runtime, and you should take extra care to say when that resource is no longer needed.
You'll have to figure that out on a case-by-case basis, by reading the documentation of the stream.
For resources allocated through dart:ffi, you can also use NativeFinalizer to register a dispose function for the resource.
Generally, you should always cancel the subscription if you don't need any more events from a stream. That's the one thing you can do. If nothing else, it allows garbage collection to collect things a little earlier.

UIDocument synchronous read - completion handler stalled in dispatch

I tried multiple ways of wrapping a file read within a synchronous method call (including using multiple queues, specifying target queues, setting up an NSThread and signalling with NSCondition's, even moving the allocation of the UIDocument to the background thread in the end, and also trying dispatch_sync on the background queue as well).
What ended up consistently happening is the completion handler for UIDocument.openWithCompletionHandler wasn't executing, although the documentation indicates that shall happen on the same queue that initiated the openWithCompletionHandler call.
I figured this has ultimately something to do with the control not being returned by the outer/top-level method call to the run loop. It would seem that regardless of what other queues or threads are being set up, the dispatch system expects me to return from the outermost method call, or things get blocked. This would however defeat the whole synchronous design approach.
My use case requires synchronous file reads (with very small data sizes), and I'd prefer the convenience of UIDocument over moving to lower level methods, or looking at ways to introduce async patterns. I reckon UIDocument was designed for more conventional cases, I understand well enough the ubiquity - and in most cases user friendliness and efficiency of async patterns, but in this case it would present a cumbersome situation for both development and user experience.
I wonder if there is something else that could be tried with dispatch queues that could still be explored (like manually consuming events from a queue, creating a custom run loop) that could avoid this seemingly global synchronization effect.
EDIT: this is for an Audio Unit app extension. Instantiation is controlled by the platform, and a "half-initialized" state could become a problematic situation. It is pretty much standard in the industry to fully load the plugin before even allowing the host app to start playing any audio for example, not to mention starting to stream MIDI/automation events. (That's not to say there aren't extensions with crazy load times that could take another look at their design, but in most cases these are well justified in this domain).

Is there a way to have a future complete when a Stream is "done" without actually draining the messages, in Dart?

I want to see if the other side gave up and closed the sink of a StreamChannel, without actually reading the messages yet.
(I'm going to be handing the stream to someone else, so i can't listen() to it, since you're only allowed to listen once per stream.)
[posting for a friend, credit to them for asking the question]
In short, no.
There is no concept of "giving up". If you put events into a non-broadcast stream, they'll stay there until someone listens to the stream (which is why you shouldn't put data there until someone listens, you're just wasting memory).
That includes the done event, and you won't get to the done event without first reading all the preceding events. That's the core abstraction of a stream - a source of events accessed in order, it's not done until it's actually done.
What I think you are looking for is a "side channel" that can communicate information about the stream without going through the stream (that is, out-of-band).
Something like that can surely be built - in about one gazillion different ways, depending on what you want, but it's just not something that a Stream supports by default, nor does a StreamChannel, if I read it correctly (I have never used a StreamChannel myself).

Is there an Erlang behaviour that can act on its own instead of waiting to be called?

I'm writing an Erlang application that requires actively polling some remote resources, and I want the process that does the polling to fit into the OTP supervision trees and support all the standard facilities like proper termination, hot code reloading, etc.
However, the two default behaviours, gen_server and gen_fsm seem to only support operation based on callbacks. I could abuse gen_server to do that through calls to self or abuse gen_fsm by having a single state that always loops to itself with a timeout 0, but I'm not sure that's safe (i.e. doesn't exhaust the stack or accumulate unread messages in the mailbox).
I could make my process into a special process and write all that handling myself, but that effectively makes me reimplement the Erlang equivalent of the wheel.
So is there a behavior for code like this?
loop(State) ->
do_stuff(State), % without waiting to be called
loop(NewState).
And if not, is there a safe way to trick default behaviours into doing this without exhausting the stack or accumulating messages over time or something?
The standard way of doing that in Erlang is by using erlang:send_after/3. See this SO answer and also this example implementation.
Is it possible that you could employ an essentially non OTP compliant process? Although to be a good OTP citizen, you do ideally want to make your long running processes into gen_server's and gen_fsm's, sometimes you have to look beyond the standard issue rule book and consider why the rules exist.
What if, for example, your supervisor starts your gen_server, and your gen_server spawns another process (lets call it the active_poll process), and they link to each other so that they have shared fate (if one dies the other dies). The active_poll process is now indirectly supervised by the supervisor that spawned the gen_server, because if it dies, so will the gen_server, and they will both get restarted. The only problem you really have to solve now is code upgrade, but this is not too difficult - your gen_server gets a code_change callback call when the code is to be upgraded, and it could simply send a message to the active_poll process, which can make an appropriate fully qualified function call, and bingo, it's running the new code.
If this doesn't suit you for some reason and/or you MUST use gen_server/gen_fsm/similar directly...
I'm not sure that writing a 'special process' really gives you very much. If you wrote a special process correctly, such that it is in theory compliant to OTP design principals, it could still be ineffective in practice if it blocks or busy waits in a loop somewhere, and doesn't invoke sys when it should, so you really have at most a small optimisation over using gen_server/gen_fsm with a zero timeout (or by having an async message handler which does the polling and sends a message to self to trigger the next poll).
If what ever you are doing to actively poll can block (such as a blocking socket read for example), this is really big trouble, as gen_server, gen_fsm or a special process will all be stopped from fullfilling their usual obligations (which they would usually be able to either because the callback in the case of gen_server/gen_fsm returns, or because receive is called and the sys module invoked explicitly in the case of a special process).
If what you are doing to actively poll is non blocking though, you can do it, but if you poll without any delay then it effectively becomes a busy wait (it's not quite because the loop will include a receive call somewhere, which means the process will yield, giving the scheduler voluntary opportunity to run other processes, but it's not far off, and it will still be a relative CPU hog). If you can have a 1ms delay between each poll that makes a world of difference vs polling as rapidly as you can. It's not ideal, but if you MUST, it'll work. So use a timeout (as big as you can without it becoming a problem), or have an async message handler which does the polling and sends a message to self to trigger the next poll.

Delaying event handling in Flash

I'd like to delay the handling for some captured events in ActionScript until a certain time. Right now, I stick them in an Array when captured and go through it when needed, but this seems inefficient. Is there a better way to do this?
Well, to me this seems a clean and efficient way of doing that.
What do you mean by delaying? you mean simply processing them later, or processing them after a given time?
You can always set a timout to the actual processing function in your event handler (using flash.utils.setTimeout), to process the event at a precise moment in time. But that can become inefficient, since you may have many timeouts dangeling about, that need to be handled by the runtime.
Maybe you could specify your needs a little more.
edit:
Ok, basically, flash player is single threaded - that is bytecode execution is single threaded. And any event, that is dispatched, is processed immediatly, i.e. dispatchEvent(someEvent) will directly call all registered handlers (thus AS bytecode).
Now there are events, which actually are generated in the background. These come either from I/O (network, userinput) or timers (TimerEvents). It may happen, that some of these events actually occur, while bytecode is executed. This usually happens in a background thread, which passes the event (in the abstract sense of the term) to the main thread through a (de)queue.
If the main thread is busy executing bytecode, then it will ignore these messages until it is done (notice: nearly any bytecode execution is always the implicit consequence of an event (be it enter frame, or input, or timer or load operation or whatever)). When it is idle, it will look in all queues, until it finds an available message, wraps the information into an ActionScript Event object, and dispatches it as previously described.
Thus this queueing is a very low level mechanism, that comes from thread-to-thread communication (and appears in many multi-threading scenarios), and is inaccessible to you.
But as I said before, your approach both is valid and makes sense.
Store them into Vector instead of Array :p
I think it's all about how you structure your program, maybe you can assign the captured event under the related instance? So that it's all natural to process the captured event with it instead of querying from a global vector

Resources