[Proto-Scripty] Re: MessageQueue for queued ajax requests

2010-08-13 Thread T.J. Crowder
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

2010-08-13 Thread Moo
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

2010-08-13 Thread Moo
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

2010-08-13 Thread T.J. Crowder
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

2010-08-13 Thread Moo
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

2010-08-13 Thread T.J. Crowder
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