[Proto-Scripty] Re: MessageQueue for queued ajax requests
Hi, Your idle flag -- which you seem to use to mean busy processing a request, which I found *really* confusing at first :-) -- is getting cleared inappropriately whenever you pull something from your queue. I don't know that that's the problem, but it's probably wrong. The error is in your onComplete function: if (this.queue.size() 0) { console.log(queue-size 0, so enqueue next item); this.push(queued: + this.queue.shift()); } this.idle = false; // === Error if `if` above was true If there's something in the queue, you call `push`, which sets the flag, starts a new async request, and returns. But then you clear the flag, so the next time `add` gets called, it'll think it should call `push` rather than `queue.push` even though there's an outstanding request. If you just move the `this.idle = false;` line above the `if` statement, it should sort out this issue. Whether it solves the problems you described I can't say, but I suspect it'll solve at least some of them. HTH, -- T.J. Crowder Independent Software Consultant tj / crowder software / com www.crowdersoftware.com On Aug 12, 7:55 pm, Moo stuhlm...@fifty-nine.de wrote: Hi there, I want to ensure, that messages are posted in the order, they come in the stack. My tests at jsFiddle were okay, but with a quick backend (where the requests are processed very fast) the order is crap. Sometimes items are posted twice. Is there anybody who can help me out? Thank you all! var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.idle = false; }, add: function(message) { if (this.idle) { console.log(idle, so saved to queue: + message); this.queue.push(message); } else { console.log(not idle, so pushed directly: + message); this.push(message); } }, push: function(message) { this.idle = true; console.log(Ajax.Request will be called now!); new Ajax.Request(this.url + message= + encodeURIComponent(message), { onComplete: function() { console.log(successfully sent: + message); if (this.queue.size() 0) { console.log(queue-size 0, so enqueue next item); this.push(queued: + this.queue.shift()); } this.idle = false; }.bind(this) }); } }); -- You received this message because you are subscribed to the Google Groups Prototype script.aculo.us group. To post to this group, send email to prototype-scriptacul...@googlegroups.com. To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en.
[Proto-Scripty] Re: MessageQueue for queued ajax requests
Hi T.J., thank you for your reply. You are right about the idle-flag, I already renamed it :) I followed your advice and moved up the idle = false thing, but it does not work so well. With a slow connection the code below works fine: var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.busy = false; }, add: function(message) { if (this.busy) this.queue.push(message) else this.push(message); }, push: function(message) { this.busy = true; new Ajax.Request(this.url, { onSuccess: function() { alert(message); this.busy = false; if (this.queue.size() 0) { this.push(queued: + this.queue.shift()); } }.bind(this) }); } }); var mq = new MessageQueue(/ajax_html_echo/); mq.add(First); mq.add(Second); mq.add(Third); But when the backend is fast and you type the hell out of your keyboard, it seems, that the part this.push(queued: + this.queue.shift()); is never reached. There is no output with queued: My thought was, that when new messages arrive, while a request is in progess, to store them until the request is finished. Then all messages in the stack should be sent until the busy-flag is set to false. Therefore I had it below the if-condition. I saw that the guys at jQuery use a sentinel inprogress which they unshift/shift to/from the array. But I don't know if that would be helpful here. It would be super great if you have the time, to have a second look at it! Thank you so much On 13 Aug., 10:18, T.J. Crowder t...@crowdersoftware.com wrote: Hi, Your idle flag -- which you seem to use to mean busy processing a request, which I found *really* confusing at first :-) -- is getting cleared inappropriately whenever you pull something from your queue. I don't know that that's the problem, but it's probably wrong. The error is in your onComplete function: if (this.queue.size() 0) { console.log(queue-size 0, so enqueue next item); this.push(queued: + this.queue.shift());} this.idle = false; // === Error if `if` above was true If there's something in the queue, you call `push`, which sets the flag, starts a new async request, and returns. But then you clear the flag, so the next time `add` gets called, it'll think it should call `push` rather than `queue.push` even though there's an outstanding request. If you just move the `this.idle = false;` line above the `if` statement, it should sort out this issue. Whether it solves the problems you described I can't say, but I suspect it'll solve at least some of them. HTH, -- T.J. Crowder Independent Software Consultant tj / crowder software / comwww.crowdersoftware.com On Aug 12, 7:55 pm, Moo stuhlm...@fifty-nine.de wrote: Hi there, I want to ensure, that messages are posted in the order, they come in the stack. My tests at jsFiddle were okay, but with a quick backend (where the requests are processed very fast) the order is crap. Sometimes items are posted twice. Is there anybody who can help me out? Thank you all! var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.idle = false; }, add: function(message) { if (this.idle) { console.log(idle, so saved to queue: + message); this.queue.push(message); } else { console.log(not idle, so pushed directly: + message); this.push(message); } }, push: function(message) { this.idle = true; console.log(Ajax.Request will be called now!); new Ajax.Request(this.url + message= + encodeURIComponent(message), { onComplete: function() { console.log(successfully sent: + message); if (this.queue.size() 0) { console.log(queue-size 0, so enqueue next item); this.push(queued: + this.queue.shift()); } this.idle = false; }.bind(this) }); } });- Zitierten Text ausblenden - - Zitierten Text anzeigen - -- You received this message because you are subscribed to the Google Groups Prototype script.aculo.us group. To post to this group, send email to prototype-scriptacul...@googlegroups.com. To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/prototype-scriptaculous?hl=en.
[Proto-Scripty] Re: MessageQueue for queued ajax requests
Here is a working example: http://jsfiddle.net/zkuMv/ On 13 Aug., 11:43, Moo stuhlm...@fifty-nine.de wrote: Hi T.J., thank you for your reply. You are right about the idle-flag, I already renamed it :) I followed your advice and moved up the idle = false thing, but it does not work so well. With a slow connection the code below works fine: var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.busy = false; }, add: function(message) { if (this.busy) this.queue.push(message) else this.push(message); }, push: function(message) { this.busy = true; new Ajax.Request(this.url, { onSuccess: function() { alert(message); this.busy = false; if (this.queue.size() 0) { this.push(queued: + this.queue.shift()); } }.bind(this) }); } }); var mq = new MessageQueue(/ajax_html_echo/); mq.add(First); mq.add(Second); mq.add(Third); But when the backend is fast and you type the hell out of your keyboard, it seems, that the part this.push(queued: + this.queue.shift()); is never reached. There is no output with queued: My thought was, that when new messages arrive, while a request is in progess, to store them until the request is finished. Then all messages in the stack should be sent until the busy-flag is set to false. Therefore I had it below the if-condition. I saw that the guys at jQuery use a sentinel inprogress which they unshift/shift to/from the array. But I don't know if that would be helpful here. It would be super great if you have the time, to have a second look at it! Thank you so much On 13 Aug., 10:18, T.J. Crowder t...@crowdersoftware.com wrote: Hi, Your idle flag -- which you seem to use to mean busy processing a request, which I found *really* confusing at first :-) -- is getting cleared inappropriately whenever you pull something from your queue. I don't know that that's the problem, but it's probably wrong. The error is in your onComplete function: if (this.queue.size() 0) { console.log(queue-size 0, so enqueue next item); this.push(queued: + this.queue.shift());} this.idle = false; // === Error if `if` above was true If there's something in the queue, you call `push`, which sets the flag, starts a new async request, and returns. But then you clear the flag, so the next time `add` gets called, it'll think it should call `push` rather than `queue.push` even though there's an outstanding request. If you just move the `this.idle = false;` line above the `if` statement, it should sort out this issue. Whether it solves the problems you described I can't say, but I suspect it'll solve at least some of them. HTH, -- T.J. Crowder Independent Software Consultant tj / crowder software / comwww.crowdersoftware.com On Aug 12, 7:55 pm, Moo stuhlm...@fifty-nine.de wrote: Hi there, I want to ensure, that messages are posted in the order, they come in the stack. My tests at jsFiddle were okay, but with a quick backend (where the requests are processed very fast) the order is crap. Sometimes items are posted twice. Is there anybody who can help me out? Thank you all! var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.idle = false; }, add: function(message) { if (this.idle) { console.log(idle, so saved to queue: + message); this.queue.push(message); } else { console.log(not idle, so pushed directly: + message); this.push(message); } }, push: function(message) { this.idle = true; console.log(Ajax.Request will be called now!); new Ajax.Request(this.url + message= + encodeURIComponent(message), { onComplete: function() { console.log(successfully sent: + message); if (this.queue.size() 0) { console.log(queue-size 0, so enqueue next item); this.push(queued: + this.queue.shift()); } this.idle = false; }.bind(this) }); } });- Zitierten Text ausblenden - - Zitierten Text anzeigen -- Zitierten Text ausblenden - - Zitierten Text anzeigen - -- You received this message because you are subscribed to the Google Groups Prototype script.aculo.us group. To post to this group, send email to prototype-scriptacul...@googlegroups.com. To unsubscribe from this group, send email to prototype-scriptaculous+unsubscr...@googlegroups.com. For more options, visit this
[Proto-Scripty] Re: MessageQueue for queued ajax requests
Hi, The only remaining problems I'm seeing are that you're using alert (don't do that, append to the body or something, alert does awkward things) and you're using onSuccess now instead of onComplete as you were originally. onComplete is what you want to trigger the next message (Ajax calls *do* fail). The queuing seems to work when you use setTimeout to simulate async ajax: http://jsbin.com/egudo3 ...but what the actual problem is when you're doing what you're describing, I couldn't say without extensive debugging I'm afraid I don't have time to go into. Off-topic: Strongly recommend *not* leaving off semicolons and braces (your add function). You may want to minify later (semicolons) and leaving off braces in my experience (20+ years in C-like syntax) is always more trouble than it's worth. YMMV Good luck, -- T.J. On Aug 13, 10:46 am, Moo stuhlm...@fifty-nine.de wrote: Here is a working example:http://jsfiddle.net/zkuMv/ On 13 Aug., 11:43, Moo stuhlm...@fifty-nine.de wrote: Hi T.J., thank you for your reply. You are right about the idle-flag, I already renamed it :) I followed your advice and moved up the idle = false thing, but it does not work so well. With a slow connection the code below works fine: var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.busy = false; }, add: function(message) { if (this.busy) this.queue.push(message) else this.push(message); }, push: function(message) { this.busy = true; new Ajax.Request(this.url, { onSuccess: function() { alert(message); this.busy = false; if (this.queue.size() 0) { this.push(queued: + this.queue.shift()); } }.bind(this) }); } }); var mq = new MessageQueue(/ajax_html_echo/); mq.add(First); mq.add(Second); mq.add(Third); But when the backend is fast and you type the hell out of your keyboard, it seems, that the part this.push(queued: + this.queue.shift()); is never reached. There is no output with queued: My thought was, that when new messages arrive, while a request is in progess, to store them until the request is finished. Then all messages in the stack should be sent until the busy-flag is set to false. Therefore I had it below the if-condition. I saw that the guys at jQuery use a sentinel inprogress which they unshift/shift to/from the array. But I don't know if that would be helpful here. It would be super great if you have the time, to have a second look at it! Thank you so much On 13 Aug., 10:18, T.J. Crowder t...@crowdersoftware.com wrote: Hi, Your idle flag -- which you seem to use to mean busy processing a request, which I found *really* confusing at first :-) -- is getting cleared inappropriately whenever you pull something from your queue. I don't know that that's the problem, but it's probably wrong. The error is in your onComplete function: if (this.queue.size() 0) { console.log(queue-size 0, so enqueue next item); this.push(queued: + this.queue.shift());} this.idle = false; // === Error if `if` above was true If there's something in the queue, you call `push`, which sets the flag, starts a new async request, and returns. But then you clear the flag, so the next time `add` gets called, it'll think it should call `push` rather than `queue.push` even though there's an outstanding request. If you just move the `this.idle = false;` line above the `if` statement, it should sort out this issue. Whether it solves the problems you described I can't say, but I suspect it'll solve at least some of them. HTH, -- T.J. Crowder Independent Software Consultant tj / crowder software / comwww.crowdersoftware.com On Aug 12, 7:55 pm, Moo stuhlm...@fifty-nine.de wrote: Hi there, I want to ensure, that messages are posted in the order, they come in the stack. My tests at jsFiddle were okay, but with a quick backend (where the requests are processed very fast) the order is crap. Sometimes items are posted twice. Is there anybody who can help me out? Thank you all! var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.idle = false; }, add: function(message) { if (this.idle) { console.log(idle, so saved to queue: + message); this.queue.push(message); } else { console.log(not idle, so pushed directly: + message); this.push(message); } }, push: function(message) { this.idle = true;
[Proto-Scripty] Re: MessageQueue for queued ajax requests
Thanks T.J., your code seems to work quite nice. I updated mine with your hints. I also removed the alert and replaced it with an update of a container. It was used for debugging purposes only. I also added a button, to trigger the add-function by hand. The problem is, that when you click on the button multiple times (e.g. 3 times) very quickly, it outputs two messages. 2 were added, 2 were sent. If you have a small timeout between clicks (maybe half a second), the messages are stored to the queue properly... It seems that there is no reliable technique to save all user-inputs which were made in short periods of time :( Here is an updated version: http://jsfiddle.net/zkuMv/2/ Thank you so much and I can understand, that you can't dive into detail so much. Geetings Moo On 13 Aug., 14:23, T.J. Crowder t...@crowdersoftware.com wrote: Hi, The only remaining problems I'm seeing are that you're using alert (don't do that, append to the body or something, alert does awkward things) and you're using onSuccess now instead of onComplete as you were originally. onComplete is what you want to trigger the next message (Ajax calls *do* fail). The queuing seems to work when you use setTimeout to simulate async ajax:http://jsbin.com/egudo3 ...but what the actual problem is when you're doing what you're describing, I couldn't say without extensive debugging I'm afraid I don't have time to go into. Off-topic: Strongly recommend *not* leaving off semicolons and braces (your add function). You may want to minify later (semicolons) and leaving off braces in my experience (20+ years in C-like syntax) is always more trouble than it's worth. YMMV Good luck, -- T.J. On Aug 13, 10:46 am, Moo stuhlm...@fifty-nine.de wrote: Here is a working example:http://jsfiddle.net/zkuMv/ On 13 Aug., 11:43, Moo stuhlm...@fifty-nine.de wrote: Hi T.J., thank you for your reply. You are right about the idle-flag, I already renamed it :) I followed your advice and moved up the idle = false thing, but it does not work so well. With a slow connection the code below works fine: var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.busy = false; }, add: function(message) { if (this.busy) this.queue.push(message) else this.push(message); }, push: function(message) { this.busy = true; new Ajax.Request(this.url, { onSuccess: function() { alert(message); this.busy = false; if (this.queue.size() 0) { this.push(queued: + this.queue.shift()); } }.bind(this) }); } }); var mq = new MessageQueue(/ajax_html_echo/); mq.add(First); mq.add(Second); mq.add(Third); But when the backend is fast and you type the hell out of your keyboard, it seems, that the part this.push(queued: + this.queue.shift()); is never reached. There is no output with queued: My thought was, that when new messages arrive, while a request is in progess, to store them until the request is finished. Then all messages in the stack should be sent until the busy-flag is set to false. Therefore I had it below the if-condition. I saw that the guys at jQuery use a sentinel inprogress which they unshift/shift to/from the array. But I don't know if that would be helpful here. It would be super great if you have the time, to have a second look at it! Thank you so much On 13 Aug., 10:18, T.J. Crowder t...@crowdersoftware.com wrote: Hi, Your idle flag -- which you seem to use to mean busy processing a request, which I found *really* confusing at first :-) -- is getting cleared inappropriately whenever you pull something from your queue. I don't know that that's the problem, but it's probably wrong. The error is in your onComplete function: if (this.queue.size() 0) { console.log(queue-size 0, so enqueue next item); this.push(queued: + this.queue.shift());} this.idle = false; // === Error if `if` above was true If there's something in the queue, you call `push`, which sets the flag, starts a new async request, and returns. But then you clear the flag, so the next time `add` gets called, it'll think it should call `push` rather than `queue.push` even though there's an outstanding request. If you just move the `this.idle = false;` line above the `if` statement, it should sort out this issue. Whether it solves the problems you described I can't say, but I suspect it'll solve at least some of them. HTH, -- T.J. Crowder Independent Software Consultant tj / crowder software / comwww.crowdersoftware.com On Aug 12, 7:55 pm, Moo stuhlm...@fifty-nine.de wrote: Hi there,
[Proto-Scripty] Re: MessageQueue for queued ajax requests
Hi, That fiddle didn't work for me, but when I forked it and moved the message stuff out to its own function (you were working way too hard there with the new Element thing, btw) it started working. Here's the fork: http://jsfiddle.net/NMPyV/1/ Let me guess: You're using Internet Explorer to test, right? Because when you click a button twice in rapid succession on IE, it registers a click followed by a dblclick, *not* two separate clicks. On Chrome or FF, you get two separate clicks (followed by a dblclick). If I change the button to a text box and hook keydown, or if I hook both click and dblclick (but the latter only on IE), no matter how close together my events (keypresses or clicks), they show up, regardless of which browser I'm using. If the backend is slow (like jsFiddle), things queue correctly; if not (my local machine), they show up correctly without being queued. By putting in a short delay on my local machine, I was able to easily make things queue or not by clicking faster or slower. The code probably isn't the way I'd do it (I don't like the fact it relies on getting a completion event, seems to me that's asking to stall because 'net communication is...not entirely reliable), but it should work barring net issues. (I'd probably add some kind of timeout; if a request has been started but I haven't seen any kind of completion event at *all* for X time, I'd probably time out the message. I'd also give them unique IDs so I knew that had happened, if the completion event showed up later. Etc.) Here's my very, very slightly modified version of your fiddle (without event changes, but those are described above): http://jsfiddle.net/NMPyV/1/ FWIW, -- T.J. On Aug 13, 2:07 pm, Moo stuhlm...@fifty-nine.de wrote: Thanks T.J., your code seems to work quite nice. I updated mine with your hints. I also removed the alert and replaced it with an update of a container. It was used for debugging purposes only. I also added a button, to trigger the add-function by hand. The problem is, that when you click on the button multiple times (e.g. 3 times) very quickly, it outputs two messages. 2 were added, 2 were sent. If you have a small timeout between clicks (maybe half a second), the messages are stored to the queue properly... It seems that there is no reliable technique to save all user-inputs which were made in short periods of time :( Here is an updated version:http://jsfiddle.net/zkuMv/2/ Thank you so much and I can understand, that you can't dive into detail so much. Geetings Moo On 13 Aug., 14:23, T.J. Crowder t...@crowdersoftware.com wrote: Hi, The only remaining problems I'm seeing are that you're using alert (don't do that, append to the body or something, alert does awkward things) and you're using onSuccess now instead of onComplete as you were originally. onComplete is what you want to trigger the next message (Ajax calls *do* fail). The queuing seems to work when you use setTimeout to simulate async ajax:http://jsbin.com/egudo3 ...but what the actual problem is when you're doing what you're describing, I couldn't say without extensive debugging I'm afraid I don't have time to go into. Off-topic: Strongly recommend *not* leaving off semicolons and braces (your add function). You may want to minify later (semicolons) and leaving off braces in my experience (20+ years in C-like syntax) is always more trouble than it's worth. YMMV Good luck, -- T.J. On Aug 13, 10:46 am, Moo stuhlm...@fifty-nine.de wrote: Here is a working example:http://jsfiddle.net/zkuMv/ On 13 Aug., 11:43, Moo stuhlm...@fifty-nine.de wrote: Hi T.J., thank you for your reply. You are right about the idle-flag, I already renamed it :) I followed your advice and moved up the idle = false thing, but it does not work so well. With a slow connection the code below works fine: var MessageQueue = Class.create({ initialize: function(url) { this.url = url; this.queue = []; this.busy = false; }, add: function(message) { if (this.busy) this.queue.push(message) else this.push(message); }, push: function(message) { this.busy = true; new Ajax.Request(this.url, { onSuccess: function() { alert(message); this.busy = false; if (this.queue.size() 0) { this.push(queued: + this.queue.shift()); } }.bind(this) }); } }); var mq = new MessageQueue(/ajax_html_echo/); mq.add(First); mq.add(Second); mq.add(Third); But when the backend is fast and you type the hell out of your keyboard, it seems, that the part this.push(queued: + this.queue.shift()); is never reached. There is no output with queued: My thought was, that when new