Some data losts when I use NSURLConnection to get data asynchronously - cocoa

I deal with the data and do some UI working according to the data in the method
-(void)connection:didReiveiceData(I use delegate as callback), and I find that UI working is always not finished completely.Maybe when the data is received, the UI threading is still busy, so some data losts.You may suggest me to deal with data in -(void)connectionFinishLoading:,it will cause other problems.

You've correctly suggested you need to process the received data in connectionDidFinishLoading:.
Before that, you need to collect all the receivedData (eg into an NSMutableData instance). Append the received data each time didReceiveData: is called (it may be called multiple times before it finishes).

the reason why some data lost is all about the method –rangeOfData:options:range:
I use it wrong.BTW, I think this method is very weird,the option accept only one of two value, NSDataSearchBackwards and NSDataSearchAnchored.why no "NSDataSearchForewards" or something like that?

Related

Ruby Sockets and parallel event handling

I'm writing a library that can interact with a socket server that transmits data as events to certain actions my library sends it.
I created an Actions module that formats the actions so that the server can read it. It also generates an action_id, because the events parser can identify it with the action that sent it. There are more than one event per action possible.
While I'm sending my action to the server, the event parser is still getting data from the server, so they work independent from each other (but then again they do work together: events response aggregator triggers the action callback).
In my model, I want to get a list of some resource from the server. The server sends its data one line at a time, but that's being handled by the events aggregator, so don't worry about that.
Okay, my problem:
In my model I am requesting the resources, but since the events are being parsed in another thread, I need to do a "infinite" loop that checks if the list is filled, and then break out to return it to the consumer of the model (e.g. my controller).
Is there another (better) way of doing this or am I on the right track? I would love your thoughts :)
Here is my story in code: https://gist.github.com/anonymous/8652934
Check out Ruby EventMachine.
It's designed to simplify this sort of reactor pattern application.
It depends on the implementation. In the code you provide you're not showing how actually the request and responses are processed.
If you know exactly the number of responses you're supposed to receive, in each one you could check if all are completed, then execute an specific action. e.g.
# suppose response_receiver is the method which receives the server response
def response_receiver data
#responses_list << data
if #response_list.size == #expected_size
# Execute some action
end
end

Why we send id instead of whole object in workers?

In Ruby practice is to send id instead of object in workers. Isn't that kind of CPU consuming process because we have to retrieve Object again from database.
Several reasons:
Saves space on the queue, also transfer time (app => queue, queue => workers).
Often it is easier to fetch fresh object from the database (as opposed to retrieving cached copy from the queue)
Argument to Resque.enqueue must be JSON-serializable. Complex objects not always can be serialized.
If you think about it the reasons are pretty obvious:
your object may change between the time te action is queued and handled and in general you don't want an outdated object.
an id a a lot lighter to transport than a whole object which you will need to serialize it in json/yaml or anything else.
if you need the associations the problem just got even worse :)
But in the end it depends on your application, if you only need some informations you can just send them to your worker directly without even using the full model.

Pause the execution of a process for a while in ejb

I think I may not be the first one with this problem.
Sometimes, the user submits a bunch of data to the server, and these data
is going to be displayed in the response page. In order to give users the illusion
that the data submission and process is fast. We usually do this asynchronously.
Now the problem is, for some reason, these data need to go to database first,
and be fetched to appear in the response page. If the response page is displayed
to the user too fast, asynchronous submission may not finish; Now I call
Thread.sleep();
before I call I setResponsePage().
but native thread is not recommended in EJB. Anyone knows alternatives ? Thanks
It's just been discussed in this question: Thread.sleep() in an EJB.
I'd split the logic into two EJBs: one for inserting the user data into DB, and one for fetching it. Your web layer would call one after the other, resulting in two separate transactions, which should be ordered properly by the database (still, it might depend on other factors, like transaction isolation).
EDIT
The problem with sleep() is that you never know how long to wait, so it's almost always a bad idea. I see a case here for Ajax push — your EJB should return immediately with a page to which data will be pushed when processing is complete. I won't advise you further on this topic, as I'm far from expertise in this area.
A still imperfect, but better than sleep(), could be syncing on database locks: first EJB would insert data and lock some record in its transaction, the second EJB would try to lock the same record and read the data. This way the second EJB would wait for minimal time that's needed.

Large number of concurrent ajax calls and ways to deal with it

I have a web page which, upon loading, needs to do a lot of JSON fetches from the server to populate various things dynamically. In particular, it updates parts of a large-ish data structure from which I derive a graphical representation of the data.
So it works great in Chrome; however, Safari and Firefox appear to suffer somewhat. Upon the querying of the numerous JSON requests, the browsers become sluggish and unusable. I am under the assumption that this is due to the rather expensive iteration of said data structure. Is this a valid assumption?
How can I mitigate this without changing the query language so that it's a single fetch?
I was thinking of applying a queue that could limit the number of concurrent Ajax queries (and hence also limit the number of concurrent updates to the data structure)... Any thoughts? Useful pointers? Other suggestions?
In browser-side JS, create a wrapper around jQuery.post() (or whichever method you are using)
that appends the requests to a queue.
Also create a function 'queue_send' that will actually call jQuery.post() passing the entire queue structure.
On server create a proxy function called 'queue_receive' that replays the JSON to your server interfaces as though it came from the browser, collects the results into a single response, sends back to browser.
Browser-side queue_send_success() (success handler for queue_send) must decode this response and populate your data structure.
With this, you should be able to reduce your initialization traffic to one actual request, and maybe consolidate some other requests on your website as well.
in particular, it updates parts of a largish data structure from which i derive a graphical representation of the data.
I'd try:
Queuing responses as they come in, then update the structure once
Hiding the representation invisible until the responses are in
Magicianeer's answer is also good - but I'm not sure if it fits your definition of "without changing the query language so that it's a single fetch" - it would avoid re-engineering existing logic.

Is NSPasteboard thread-safe?

Is it safe to write data to an NSPasteboard object from a background thread? I can't seem to find a definitive answer anywhere. I think the assumption is that the data will be written to the pasteboard before the drag begins.
Background:
I have an application that is fetching data from Evernote. When the application first loads, it gets the meta data for each note, but not the note content. The note stubs are then listed in an outline view. When the user starts to drag a note, the notes are passed to the background thread that handles getting the note content from Evernote. Having the main thread block until the data is gotten results in a significant delay and a poor user experience, so I have the [outlineView:writeItems:toPasteboard:] function return YES while the background thread processes the data and invokes the main thread to write the data to the pasteboard object. If the note content gets transferred before the user drops the note somewhere, everything works perfectly. If the user drops the note somewhere before the data has been processed... well, everything blocks forever. Is it safe to just have the background thread write the data to the pasteboard?
You can promise the data to the pasteboard without actually having the data yet.
One way is to declare the type of the data on the pasteboard, passing yourself as the pasteboard's owner, and respond to a pasteboard:provideDataForType: message by providing the data (blocking, if necessary, until the data either arrives or fails to arrive). This means that you'll need to remember which objects were copied (by stashing them in an array, for example) so you can extract/generate the data from them when the promise comes due.
The other way, referenced in Harald Scheirich's answer, is to make your model objects conform to the NSPasteboardWriting protocol, ideally in a category (to separate interface-independent logic from Mac-specific logic). This is much cleaner than the old way, but requires Mac OS X 10.6 and later.
With NSPasteboardWriting, you'll implement promises by having the model objects' writingOptionsForType:pasteboard: method return the NSPasteboardWritingPromised option. Their pasteboardPropertyListForType: method will return the data, or at least try to—as before, this method should block until the data either arrives or fails to arrive.
Oh, and to answer the question in the title (“Is NSPasteboard thread-safe?”): There's no specific answer in the Thread Safety Summary, but there is this general statement:
… mutable objects are generally not thread-safe. To use mutable objects in a threaded application, the application must synchronize appropriately.
I would consider an NSPasteboard to be a mutable object, so no.
In practice, this isn't a problem: You typically only work with NSPasteboard in response to an action message (e.g., copy:), a drag, or a service invocation, and those all only happen on the main thread anyway. For them to happen on a secondary thread, you would have to explicitly send such messages yourself from code running on a secondary thread, in which case you are already doing something very wrong.
Conjecture:
I think your problem has nothing to do with threading but the fact that by returning YES you told the system that the data is ready. have you tried moving your data into a custom class supporting NSPasteboardWriting and NSPasteboardReading? this way the accessor to your data can block until the data is ready.
See the Pasteboard Documentation

Resources