Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

getting result of async streamMessage

1 view
Skip to first unread message

Red_Se...@hotmail.de

unread,
Mar 23, 2009, 10:03:45 AM3/23/09
to
Hello,
I'm kind of stuck once again. So far I've read the content of an email
synchronous. However there are those emails with big attachments,
which then result in these 'Stop script' prompts and several seconds
wait for the user so I thought about making it asynchronous. That
worked all righ, however I don't get the result as I wanted. While the
async Stream is reading, I wanted to do a bit and eventually open a
dialog, in which the user gets to perform a few actions. Once he
clicks on OK, I need the complete email to perform a few actions on
it. It is no problem with the usual small mails, however with these
big mails, I don't know how to tell TB to check whether the final
result is there every few milliseconds. Using a While-Solution freezes
everything as the CPU is busy working on the While-part. I then read a
bit along and found setTimeout() and setIntervall() as was proposed in
other forums.
Here my code: I'll explain what I tried out so far afterwards.

var msg_service = messenger.messageServiceFromURI(uri);
var msg_stream = AsyncStream();
try {
msg_service.streamMessage(uri, msg_stream, msgWindow, null,
false, null);
}catch (ex) {
log(ex)
}
/*do something*/
var params = {inn:{msg_stream:msg_stream}, out:null};
window.openDialog("chrome://test/content/dialog.xul","test-
dialog","chrome, dialog, modal",params).focus();
}

function AsyncStream() {
var aListener = {
_first: true,
_data: null,
_finaldata: null,

QueryInterface : function(iid) {
if (iid.equals
(Components.interfaces.nsIStreamListener) ||
iid.equals
(Components.interfaces.nsIMsgHeaderSink) ||
iid.equals(Components.interfaces.nsISupports))
{
return this;
} else {
throw Components.results.NS_NOINTERFACE;
return 0;
}
},

onStartRequest : function (aRequest, aContext) {
},

onStopRequest : function (aRequest, aContext, aStatusCode)
{
this._finaldata = this._data;
},

onDataAvailable : function (aRequest, aContext,
aInputStream, aOffset, aCount) {
var binInputStream = Components.classes["@mozilla.org/
binaryinputstream;1"].createInstance
(Components.interfaces.nsIBinaryInputStream);
binInputStream.setInputStream(aInputStream);
if (this._first) {
this._data = binInputStream.readBytes
(binInputStream.available());
this._first = false;
} else{
this._data += binInputStream.readBytes
(binInputStream.available());
binInputStream.close();
}
},
};
return aListener;
}

The code from the dialog:

custombutton_accept = function(){
msg_stream = window.arguments[0].inn.msg_stream;
var lade = window.setInterval("wait_until_finished(msg_stream)",
500);

function wait_until_finished(stream){
if(stream._finaldata){
log(stream._finaldata);
window.clearInterval(lade);
get_body(stream._finaldata);
}
};

function get_body(body){
alert(body);
return true;
};

return true;
}

Since I want to check every x ms I tried using setInterval, however
the dialog simply gets closed as the code isn't stopped after
setInterval, instead it simply continues and closes the dialog. I
waited a bit to see if afterwards something happened but there never
came anything.

I also tried setTimeout:

custombutton_accept = function(){
msg_stream = window.arguments[0].inn.msg_stream;
wait_until_finished(msg_stream);
}

wait_until_finished = function(stream){
if(stream._finaldata){
log(stream._finaldata);
get_body(stream._finaldata);
}else{
window.setTimeout("wait_until_finished(stream)",500);
}
}

get_body = function(body){
/*do something*/
alert(body);
}

Same problem as with setInterval.

A combination of while and setInterval:

wait_until_finished = function(stream){
while( !stream._finaldata() ){
setTimeout('wait_until_finished(stream)', 100)
}
get_body(stream._finaldata());
}
This froze the ui as if you just used while, since the code doesn't
stop after setInterval.

I don't know what else to try. Any tipps/hints/code examples are
greatly appreciated.

Greetings,
Serratia

0x000000

unread,
Mar 24, 2009, 5:22:48 AM3/24/09
to
On Mar 23, 3:03 pm, "Red_Serra...@hotmail.de"

I think it's best to use the event queue service object instead of
setting timeouts which pretty much stalls the entire UI thread while
still being mixed in with current browser thread: @mozilla.org/event-
queue-service

----------------------------------8<----------------------------------
Components.classes["@mozilla.org/event-queue-service;1"].getService
(Components.interfaces.nsIEventQueueService)
---------------------------------->8----------------------------------

And use an asynchrounous request to resolve it, but you'll have to
embed the listener in the object while resolving it so that it can
notify the listener when data is available, or stopped. Like:
onDataAvailable.

Please correct me if I'm wrong or don't understand your question
properly.

/rvdh

Neil

unread,
Mar 24, 2009, 5:46:36 AM3/24/09
to
Red_Se...@hotmail.de wrote:

>custombutton_accept = function(){
> msg_stream = window.arguments[0].inn.msg_stream;
> wait_until_finished(msg_stream);
>}
>
>

A dialog's accept button will close the dialog unless you return false here.

Rather than using a timeout, you might consider adding an extra callback
property to the stream something like this:

onStopRequest : function (aRequest, aContext, aStatusCode) {

this._finalData = this._data;
if (this._callback)
this._callback(this._finalData);
},

custombutton_accept = function() {
function get_body(body) {
alert(body);
window.close();
}
var msg_stream = window.arguments[0].inn.msg_stream;
if (msg_stream._finalData)
get_body(msg_stream._finalData);
else
msg_stream._callback = get_body;
return false;
}

Not shown: code to cancel the callback when the dialog is cancelled;
code to deal with clicking OK twice; etc.

--
Warning: May contain traces of nuts.

Serratia

unread,
Mar 24, 2009, 7:33:08 AM3/24/09
to

nsIEventQueueServide doesn't seem to exist in the current versions.
According to http://markmail.org/message/2p63wgqhzwtpujiy it has been
replaced by nsIThreadManager, which I knew about but in through
http://groups.google.com/group/mozilla.dev.extensions/browse_frm/thread/bd2624ca5169915a/fe79dec301a06d2f?lnk=gst&q=nsIThread#fe79dec301a06d2f
I got discouraged in reading in further.

Greetings,
Serratia

Serratia

unread,
Mar 24, 2009, 7:35:18 AM3/24/09
to
On 24 Mrz., 10:46, Neil <n...@parkwaycc.co.uk> wrote:

This worked excellent, so thank you very much. =) This is quite a
beautiful solution.

Greetings,
Serratia

0 new messages