Re: How to throttle rate of NSInputStream?
Re: How to throttle rate of NSInputStream?
- Subject: Re: How to throttle rate of NSInputStream?
- From: Roland King <email@hidden>
- Date: Tue, 27 Mar 2012 22:31:18 +0800
On Mar 27, 2012, at 7:13 AM, Jens Alfke wrote:
> [I posted this to macnetworkprog earlier today, but 3 hours later it hasn’t shown up yet, so I’m trying here too.]
>
> I’m using an async NSInputStream to read from a TCP socket. Given a good connection, the data comes in faster than an iOS device can parse it (it’s a stream of small JSON docs, one per line.) I’m performance-tuning my code, and finding that NSInputStream is shoving all of the data down my throat at once, without giving the runloop a chance to process any other input sources. This means that my thread is blocked, and other tasks scheduled on it don’t get a chance to run, until I’ve read the whole feed, which takes over a minute. (And there’s also the fact that CFNetwork must be buffering megabytes of data from the socket that my code hasn’t read yet.)
>
> This seems to hinge on the way the stream calls my event handler. When I get the NSStreamEventHasBytesAvailable, I only read 8k bytes of data at a time, then return. What seems to happen is that, if that didn’t consume all of the available data, the stream will keep sending me the event in a tight loop without exiting back to the runloop in between.
>
> What can I do about this? Ideally I’d like the stream to hold off on reading more from the socket until my code finishes processing the buffer. As a second choice, I’d like it to at least return the runloop more often so my other tasks get time to run.
>
> —Jens
>
Don't think you have any control to do that. The TCP connection runs in the kernel and shoves data at you. If the NSInputStream was at that level then perhaps not reading would eventually fill a kernel buffer and stop the flow, but probably not what's happening here. So the data is going to come in whether you like it or not and it's going to queue up somewhere. Once of course you've read it from the NSInputStream, you've moved it from one place to another, so if you assume you can't stop it flowing in, doesn't really matter if you read it or not, you're just moving it around buffers. If it's megabytes of data, then it is, megabytes of data is one camera image, the phone should have enough storage unless you have REALLY insane feeds.
In this case I'd probably read the data in 8kb chunks, if that's the size you like, as fast as I possibly can and throw those chunks on an operation queue or something for later processing. Just get the stream read as fast as you can and move the data elsewhere, then process it at the speed you can.
Alternatively, if this is an HTTP style request can you ask for the data in chunks, HTTP supports it, get a bit, process it, get the next bit.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden