[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-07 Thread Eric Ayers

The most important issue in my mind is that it isn't always
appreciated to take a minor feature change that very few developers
will ever use and use it as an excuse to mix up the existing API.
Take, in contrast, the xxxListener to xxxHandler change.  There was a
lot of pain in that one, but it resulted in significant benefits for a
majority of developers.

On Sun, Sep 6, 2009 at 9:18 PM,
brett.wooldridgebrett.wooldri...@gmail.com wrote:

 As a long time Java programmer (since v0.9!), I'd just like to throw
 in that I don't see any particular practical benefit to leveraging
 Runnable or CallableV.  Sure, they are just interfaces, and you
 could re-use them.  But beyond that, especially with respect to
 CallableV, almost nothing execution related from
 java.util.concurrent is applicable to thread-less JavaScript.
 Borrowing one interface from java.util.concurrent because it has the
 same signature, yet not implementing any of the java.util.concurrent
 features is more confusing to a Java programmer coming to GWT.

 So while I appreciate Eric's point of view, I don't share it.  Jason's
 suggestion of re-using Executor and ExecutorService is also likely not
 practicable in GWT because of ExecutorService's blocking methods
 (invokeAll(), awaitTermination).

 Ray's last suggestion gets my vote.  It looks substantially like the
 existing pattern and does not inject unnecessary new controller or
 scheduler classes.  I'm of the simplest thing that can possibly work
 school of thought as of late.

 Brett Wooldridge

 




-- 
Google Code Jam 2009
http://code.google.com/codejam

--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-06 Thread brett.wooldridge

As a long time Java programmer (since v0.9!), I'd just like to throw
in that I don't see any particular practical benefit to leveraging
Runnable or CallableV.  Sure, they are just interfaces, and you
could re-use them.  But beyond that, especially with respect to
CallableV, almost nothing execution related from
java.util.concurrent is applicable to thread-less JavaScript.
Borrowing one interface from java.util.concurrent because it has the
same signature, yet not implementing any of the java.util.concurrent
features is more confusing to a Java programmer coming to GWT.

So while I appreciate Eric's point of view, I don't share it.  Jason's
suggestion of re-using Executor and ExecutorService is also likely not
practicable in GWT because of ExecutorService's blocking methods
(invokeAll(), awaitTermination).

Ray's last suggestion gets my vote.  It looks substantially like the
existing pattern and does not inject unnecessary new controller or
scheduler classes.  I'm of the simplest thing that can possibly work
school of thought as of late.

Brett Wooldridge

--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-04 Thread Bruce Johnson
I'm definitely not a Java pedant, so maybe there's something
wrong/underinformed with my perspective here, but here's my take...
1) Why Runnable isn't quite right
- Has close associations with threads
- Isn't spec'd to throw Throwable, which means what could be simple callbaks
have to always have try/catch that then invoke exactly the same code path
that the uncaught exception handler would've called anyway.

2) Callable is closer, but it has a close association with the Executor
family, which itself has lots of connotations, most of which we can't honor.

3) I see the spritual similarity to ExecutorService/Future, but I don't see
that there's any proper subset we could implement that would cover the same
use cases. Even if we could, the standard Java for that subset could be
misleading relative to the semantics we are trying to guarantee -- that is,
we'd like to say stuff like runs at the next opporuntity after the event
loop has been processed at least once in the GWT javadoc, otherwise it
comes across as way too abstract.

Perhaps an approach would be to try to perfect the API without trying to
reconcile it, then see if we can map it onto the existing JRE without losing
anything vital.


On Thu, Sep 3, 2009 at 11:21 PM, Ray Cromwell cromwell...@gmail.com wrote:


 Is there a reason why we just don't add Runnable and CallableV to the JRE
 emul and use those instead of Command? This design seems to parallel some of
 the patterns in ExecutorService. I could see some of those patterns being
 useful (like completion queues, which would be useful for staged
 animations).
 -Ray


 On Thu, Sep 3, 2009 at 7:08 PM, Bruce Johnson br...@google.com wrote:

 Okay, here's a strawman for a new-and-improved proposal. All these would
 be in core.
 // Deferred command = on the other side of the event loop
 interface DeferredCommands {
   public static DeferredCommands get();

   public void add(Command cmd);
   public void add(Command cmd, boolean asap);  // asap = faster than
 setTimeout(0)
   public void addPause();
 }

 // Finally command = before you end the current stack trace
 interface FinallyCommands {
   public static FinallyCommands get();

   public void add(Command cmd);
 }

 // Incremental command = call repeatedly quickly to avoid SSWs
 interface IncrementalCommands {
   public static IncrementalCommands get();

   public void add(Command cmd);
   public void add(Command cmd, boolean asap);
 }

 // Timed command = call based clock time (aka regular old timers)
 interface TimedCommands {
   public static TimedCommand get();

   public TimerController scheduleOnce(Command cmd, int millis);
   public TimerController scheduleRecurring(Command cmd, int millis);
 }

 // Allows optional control over a timer after it's created.
 // If the return values in scheduleOnce, etc. aren't used, extra code can
 maybe optimize away.
 interface TimerController {
   public void pause();
   public void resume();
   public void cancel();
 }

 I think that maybe consolidating timers into this mix might be a bit much,
 but, then again, if we're graduating Command to core, then it seems like
 it would be nice to make it the uniform callback interface.

 -- Bruce

 On Thu, Sep 3, 2009 at 9:28 PM, Bruce Johnson br...@google.com wrote:

 I like it a lot Ray. (To be completely honest, I knew you were going to
 say all that, so I decided to sandbag and let you do the typing :-)

 I question if it's really appropriate to explicitly say PreEventLoop
 and PostEventLoop considering that...sometimes...the event loop can
 actually run re-entrantly. Those names sound like a very strong guarantee
 that I don't think we can reliably guarantee. It's more like
 PreCurrentJavaScriptStackFullyUnwinding and PostEventLoop.

 Actually, to take a step back (which is my very favorite thing to do),
 there are several kinds of things that could be consolidated:

 1) Single-shot timers
 2) Recurring timers
 3) Incremental commands that run as soon as possible after the event loop
 (faster than setTimeout(0))
 4) Incremental commands that run after the event loop via setTimeout(0)
 5) Deferred commands that run as soon as possible after the event loop
 (faster than setTimeout(0))
 6) Deferred commands that run after the event loop via setTimeout(0)
 7) Execute-this-before-you-unwind-the-JS-stack-in-which-it-was-enqueued
 (aka BatchedCommand)
 8) Arguably, runAsync (although it's purpose is so functionally different
 it would probalby be a mistake to munge it in)

 #3 and #5 might look funny, but it is generally possible to run code
 *after* the event loop but *much* sooner than setTimeout(0), which is
 usually clamped to some pretty long duration such as 10ms. The reason you
 wouldn't want to do #3 and #5 as the default for deferred commands is that
 it would keep the CPU overly busy if you did it a bunch in a row. It would
 very likely drain mobile batteries quickly, even.

 @Ray (or anyone): Can you think of an awesome way to reconcile those
 behind a 

[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-04 Thread Ray Ryan
I like the Finally name.

Since you have a single Command object used by Incremental along with
everyone else, you're implying interface

Command {
  /**
   * @return whether this command should be run again.
   * Checked only by {...@link IncrementalCommands} and {...@link TimedCommands}
   */
  boolean execute();
 }

That's a bit redundant with the TimerController--would it even be honored by
TimedCommands?

Let me propose this (actually, I think steal it from Brian Brian Slesinsky)
, to allow every command to reschedule itself or not.

rjrjr

interface Command {
  /**
   * @param dispatcher To allow this command to requeue
   *itself, or add other commands. Presto, it's
   *all three of timed, incremental and one off
   */
  void execute(CommandDispatcher dispatcher);
}

interface CommandDispatcher {
  enum When {
FINALLY,
ASAP
  }

  public static CommandDispatcher get();

  public void add(Command c);

  public void add(Command c, When w);

  public void addDeferred(Command c, int millis);
}

That's the whole thing. For convenience, we could also offer stuff like the
following. Perhaps
// better to see what evolves

abstract class IncrementalCommand implements Command {
  public void execute(CommandDispatcher dispatcher) {
if (doExecute()) {
  dispatcher.add(this);
}
  }

  /** @return true to keep going */
  abstract boolean doExecute();
}

and

public class TimedCommand implements Command {
  private final wrappedCommand;
  private final interval millis;
  private boolean stopped;

  public TimedCommand(int millis, Command wrappedCommand) {
this.wrappedCommand = wrappedCommand;
this.millis = millis;
  }

  public void stop() {
stopped = true;
  }

  public void execute(CommandDispatcher dispatcher) {
if (!stopped) {
  wrappedCommand.execute(dispatcher);
  dispatcher.add(this, millis);
}
  }
}

--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-04 Thread Ray Ryan
Because the dispatcher methods are not static you can write your code to
have the dispatcher injected, and at test time provide whatever alternative
implementation you want. So long as you don't use the static get method
outside of your Gin module or whatever, you're golden.
Not good enough?

On Fri, Sep 4, 2009 at 12:20 PM, Brian Slesinsky bslesin...@gmail.comwrote:


 How do we test methods that schedule commands?

 Maybe there should be a way to test that a method schedules some
 commands without actually executing them? From a testing point of
 view, it would be nice to be able to push a context that captures all
 commands, call the method under test, and then pop the context and
 verify that it contains the commands you expect. (The API should be
 optimized away if it's not used, which would usually be the case in
 production.)

 Alternately, you might want to have a way to force commands scheduled
 by the method under test to run before doing your assertions, so that
 you can verify that the method under test had its intended effect,
 regardless of whether it uses commands to accomplish it.  I think if
 you can capture commands, then you could do this too. (It gets tricky
 to do if commands can schedule other commands, so it's worth writing a
 test utility, but probably doesn't require anything more than
 capturing from the core API.)

 - Brian

 On Sep 3, 7:08 pm, Bruce Johnson br...@google.com wrote:
  Okay, here's a strawman for a new-and-improved proposal. All these would
 be
  in core.
  // Deferred command = on the other side of the event loop
  interface DeferredCommands {
public static DeferredCommands get();
 
public void add(Command cmd);
public void add(Command cmd, boolean asap);  // asap = faster than
  setTimeout(0)
public void addPause();
 
  }
 
  // Finally command = before you end the current stack trace
  interface FinallyCommands {
public static FinallyCommands get();
 
public void add(Command cmd);
 
  }
 
  // Incremental command = call repeatedly quickly to avoid SSWs
  interface IncrementalCommands {
public static IncrementalCommands get();
 
public void add(Command cmd);
public void add(Command cmd, boolean asap);
 
  }
 
  // Timed command = call based clock time (aka regular old timers)
  interface TimedCommands {
public static TimedCommand get();
 
public TimerController scheduleOnce(Command cmd, int millis);
public TimerController scheduleRecurring(Command cmd, int millis);
 
  }
 
  // Allows optional control over a timer after it's created.
  // If the return values in scheduleOnce, etc. aren't used, extra code can
  maybe optimize away.
  interface TimerController {
public void pause();
public void resume();
public void cancel();
 
  }
 
  I think that maybe consolidating timers into this mix might be a bit
 much,
  but, then again, if we're graduating Command to core, then it seems
 like
  it would be nice to make it the uniform callback interface.
 
  -- Bruce
 
 
 
  On Thu, Sep 3, 2009 at 9:28 PM, Bruce Johnson br...@google.com wrote:
   I like it a lot Ray. (To be completely honest, I knew you were going to
 say
   all that, so I decided to sandbag and let you do the typing :-)
 
   I question if it's really appropriate to explicitly say PreEventLoop
 and
   PostEventLoop considering that...sometimes...the event loop can
 actually
   run re-entrantly. Those names sound like a very strong guarantee that I
   don't think we can reliably guarantee. It's more like
   PreCurrentJavaScriptStackFullyUnwinding and PostEventLoop.
 
   Actually, to take a step back (which is my very favorite thing to do),
   there are several kinds of things that could be consolidated:
 
   1) Single-shot timers
   2) Recurring timers
   3) Incremental commands that run as soon as possible after the event
 loop
   (faster than setTimeout(0))
   4) Incremental commands that run after the event loop via setTimeout(0)
   5) Deferred commands that run as soon as possible after the event loop
   (faster than setTimeout(0))
   6) Deferred commands that run after the event loop via setTimeout(0)
   7) Execute-this-before-you-unwind-the-JS-stack-in-which-it-was-enqueued
   (aka BatchedCommand)
   8) Arguably, runAsync (although it's purpose is so functionally
 different
   it would probalby be a mistake to munge it in)
 
   #3 and #5 might look funny, but it is generally possible to run code
   *after* the event loop but *much* sooner than setTimeout(0), which is
   usually clamped to some pretty long duration such as 10ms. The reason
 you
   wouldn't want to do #3 and #5 as the default for deferred commands is
 that
   it would keep the CPU overly busy if you did it a bunch in a row. It
 would
   very likely drain mobile batteries quickly, even.
 
   @Ray (or anyone): Can you think of an awesome way to reconcile those
 behind
   a consistent API?
 
   On Thu, Sep 3, 2009 at 4:52 PM, Joel Webber j...@google.com wrote:
 
   ++(++Ray)
   

[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-04 Thread Eric Ayers

-1 for renaming and deprecating the DeferredCommand, etc calls unless
there is really something significant other than the name change.   As
a maintainer, I get sick of APIs moving around underneath my code and
having someone else tell me its broken.  Furthermore, you'll make
obsolete every good tutorial and blog post already written that tells
you how to do fun stuff in GWT with these tools.

On Fri, Sep 4, 2009 at 11:00 PM, Miroslav
Pokornymiroslav.poko...@gmail.com wrote:

 Slightly off topic more of a design comment.

 For me Job would be a better name than Command. Command reminds me of
 the command pattern while job is always a background task that might
 execute sooner or later.

 It also seems like there are lots of duplicate add methods for lack
 of a better of description, whereby each type of Command has it's own.
 What about a central manager type class with a single add( Job,
 JobType) where JobType is Incremental, Timed, etc.

 For the Timed version there would be factory to pass the when or how
 often etc, or as in the previous email from Bruce AsapJob.

 I can also see a benefit of allowing developers to change the command
 (job) type by changing the JobType parameter which seems simpler /
 more flexible than the hard coded static adds and super type.

 Just an idea...

 On 05/09/2009, at 4:35 AM, Ray Ryan rj...@google.com wrote:

 I like the Finally name.

 Since you have a single Command object used by Incremental along
 with everyone else, you're implying interface

 Command {
   /**
    * @return whether this command should be run again.
    * Checked only by {...@link IncrementalCommands} and {...@link
 TimedCommands}
    */
   boolean execute();
  }

 That's a bit redundant with the TimerController--would it even be
 honored by TimedCommands?

 Let me propose this (actually, I think steal it from Brian Brian
 Slesinsky) , to allow every command to reschedule itself or not.

 rjrjr

 interface Command {
   /**
    * @param dispatcher To allow this command to requeue
    *    itself, or add other commands. Presto, it's
    *    all three of timed, incremental and one off
    */
   void execute(CommandDispatcher dispatcher);
 }

 interface CommandDispatcher {
   enum When {
     FINALLY,
     ASAP
   }

   public static CommandDispatcher get();

   public void add(Command c);

   public void add(Command c, When w);

   public void addDeferred(Command c, int millis);
 }

 That's the whole thing. For convenience, we could also offer stuff
 like the following. Perhaps
 // better to see what evolves

 abstract class IncrementalCommand implements Command {
   public void execute(CommandDispatcher dispatcher) {
     if (doExecute()) {
       dispatcher.add(this);
     }
   }

   /** @return true to keep going */
   abstract boolean doExecute();
 }

 and

 public class TimedCommand implements Command {
   private final wrappedCommand;
   private final interval millis;
   private boolean stopped;

   public TimedCommand(int millis, Command wrappedCommand) {
     this.wrappedCommand = wrappedCommand;
     this.millis = millis;
   }

   public void stop() {
     stopped = true;
   }

   public void execute(CommandDispatcher dispatcher) {
     if (!stopped) {
       wrappedCommand.execute(dispatcher);
       dispatcher.add(this, millis);
     }
   }
 }


 

 




-- 
Google Code Jam 2009
http://code.google.com/codejam

--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-03 Thread Ray Cromwell
Could this also be used as a general pattern to batch DOM updates from
multiple Widgets performing updates? e.g. a current approach to avoid the
overhead, of say, installing a dozen widgets, is to concatenate all the HTML
together, slam it into innerHTML, and then wrap the widgets around the HTML.
But this rather breaks the nice OO design people are used to with widgets.
Templating is an alternative, but I'm wondering, why can't we make all of
the attachment stuff happen via a batch queue. A special optimizer on the
queue could even recognize instances of when DOM updates can be coalesced
and leverage documentFragment or innerHTML.
e.g.

VerticalPanel vp = ...
vp.add(new Label())
vp.add(new Label())

The objects are constructed, but the HTML mutations are deferred/queued.
When adding a DOM mutation to the queue, you could check if existing queue
data isOrHasChild the new DOM mutation element, and if so, just modify the
queue element (coalesce) rather than appending another queue item. Then,
when processing the queue, you only need to add the roots to the DOM,
attaching/modifying enmasse.

This would preserve the OO-ness of constructing widget hierarchies without
requiring 'foreign' string-based templating.

-Ray


On Wed, Sep 2, 2009 at 5:13 PM, Bruce Johnson br...@google.com wrote:

 On Wed, Sep 2, 2009 at 6:07 PM, Scott Blum sco...@google.com wrote:

 I do agree with John that we should really discuss how this can be
 implemented.


 It's already implemented!


  Is there some magic trick to make the browser execute a piece of code at
 the time you want, or do we need to go and modify all our event code (like
 with the global uncaught exception handler)?


 No trick, it's as bad as you'd hope it wasn't. On the positive side, it's
 already been done -- I'm just augmenting the tests for the various
 subsystems such as RequestBuilder and event dispatching to make sure we
 tighten the correctness noose as much as possible.

 Longer term, Bob and I both would really like to find a general mechanism
 for making this pattern easy to do from any path into a GWT module from the
 outside, exactly along the lines of what Matt was talking about. I think
 rolling this functionality into gwt-exporter (and then rolling that sort of
 functionality directly into GWT proper) will get us pretty far down the
 road.

 Code review request forthcoming, possibly tomorrow.

 -- Bruce

 


--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-03 Thread Ray Ryan
  The mechanism is just brilliant. I have reservations about the api.

bikeshed
it seemed kinda nice to have one less type

Except that we have one more type, BatchedCommand, which looks exactly like
Command, except with a different name, and you have to subclass it rather
than implement it...

A simple thing we could do is:

   - create com.google.gwt.core.client,
   - change com.google.gwt.user.client.Command to extend the new one
   - deprecate com.google.gwt.user.client.Command
   - And have BatchedCommand accept com.google.gwt.core.client

And the two names, DeferredComand and BatchedCommand, don't give much
clue as to which does what. And of course BatchedCommand doesn't actually
provide any batching service.

If we were doing all this from scratch, I suspect we would wind up with
something like this in core (presuming we're happy with IncrementalCommand
and addPause):

package com.google.gwt.core.dispatch

public interface Command {
  void execute();
}

public interface IncrementalCommand {
  boolean execute();
}

public class PreEventLoopDispatcher {
  public static PreEventLoopDispatcher get(); { ... }

  public void addCommand(Command c);
}

public class PostEventLoopDispatcher {
  public static PostEventLoopDispatcher get(); { ... }

  public void addCommand(Command c);
  public void addCommand(IncrementalCommand c);
  public void addPause();
}

Note the avoidance of statics to make commands more testable, a recurring
subject.

Seems like we could do this, deprecate the existing classes, and make them
wrappers around the new.

/bikeshed

On Wed, Sep 2, 2009 at 11:36 PM, Ray Cromwell cromwell...@gmail.com wrote:


 Could this also be used as a general pattern to batch DOM updates from
 multiple Widgets performing updates? e.g. a current approach to avoid the
 overhead, of say, installing a dozen widgets, is to concatenate all the HTML
 together, slam it into innerHTML, and then wrap the widgets around the HTML.
 But this rather breaks the nice OO design people are used to with widgets.
 Templating is an alternative, but I'm wondering, why can't we make all of
 the attachment stuff happen via a batch queue. A special optimizer on the
 queue could even recognize instances of when DOM updates can be coalesced
 and leverage documentFragment or innerHTML.
 e.g.

 VerticalPanel vp = ...
 vp.add(new Label())
 vp.add(new Label())

 The objects are constructed, but the HTML mutations are deferred/queued.
 When adding a DOM mutation to the queue, you could check if existing queue
 data isOrHasChild the new DOM mutation element, and if so, just modify the
 queue element (coalesce) rather than appending another queue item. Then,
 when processing the queue, you only need to add the roots to the DOM,
 attaching/modifying enmasse.

 This would preserve the OO-ness of constructing widget hierarchies without
 requiring 'foreign' string-based templating.

 -Ray


  On Wed, Sep 2, 2009 at 5:13 PM, Bruce Johnson br...@google.com wrote:

  On Wed, Sep 2, 2009 at 6:07 PM, Scott Blum sco...@google.com wrote:

 I do agree with John that we should really discuss how this can be
 implemented.


 It's already implemented!


  Is there some magic trick to make the browser execute a piece of code at
 the time you want, or do we need to go and modify all our event code (like
 with the global uncaught exception handler)?


 No trick, it's as bad as you'd hope it wasn't. On the positive side, it's
 already been done -- I'm just augmenting the tests for the various
 subsystems such as RequestBuilder and event dispatching to make sure we
 tighten the correctness noose as much as possible.

 Longer term, Bob and I both would really like to find a general mechanism
 for making this pattern easy to do from any path into a GWT module from the
 outside, exactly along the lines of what Matt was talking about. I think
 rolling this functionality into gwt-exporter (and then rolling that sort of
 functionality directly into GWT proper) will get us pretty far down the
 road.

 Code review request forthcoming, possibly tomorrow.

 -- Bruce

 



--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-03 Thread Scott Blum
++Ray.

On Thu, Sep 3, 2009 at 4:38 PM, Ray Ryan rj...@google.com wrote:

   The mechanism is just brilliant. I have reservations about the api.

 bikeshed
 it seemed kinda nice to have one less type

 Except that we have one more type, BatchedCommand, which looks exactly like
 Command, except with a different name, and you have to subclass it rather
 than implement it...

 A simple thing we could do is:

- create com.google.gwt.core.client,
- change com.google.gwt.user.client.Command to extend the new one
- deprecate com.google.gwt.user.client.Command
- And have BatchedCommand accept com.google.gwt.core.client

 And the two names, DeferredComand and BatchedCommand, don't give much
 clue as to which does what. And of course BatchedCommand doesn't actually
 provide any batching service.

 If we were doing all this from scratch, I suspect we would wind up with
 something like this in core (presuming we're happy with IncrementalCommand
 and addPause):

 package com.google.gwt.core.dispatch

 public interface Command {
   void execute();
 }

 public interface IncrementalCommand {
   boolean execute();
 }

 public class PreEventLoopDispatcher {
   public static PreEventLoopDispatcher get(); { ... }

   public void addCommand(Command c);
 }

 public class PostEventLoopDispatcher {
   public static PostEventLoopDispatcher get(); { ... }

   public void addCommand(Command c);
   public void addCommand(IncrementalCommand c);
   public void addPause();
 }

 Note the avoidance of statics to make commands more testable, a recurring
 subject.

 Seems like we could do this, deprecate the existing classes, and make them
 wrappers around the new.

 /bikeshed

 On Wed, Sep 2, 2009 at 11:36 PM, Ray Cromwell cromwell...@gmail.comwrote:


 Could this also be used as a general pattern to batch DOM updates from
 multiple Widgets performing updates? e.g. a current approach to avoid the
 overhead, of say, installing a dozen widgets, is to concatenate all the HTML
 together, slam it into innerHTML, and then wrap the widgets around the HTML.
 But this rather breaks the nice OO design people are used to with widgets.
 Templating is an alternative, but I'm wondering, why can't we make all of
 the attachment stuff happen via a batch queue. A special optimizer on the
 queue could even recognize instances of when DOM updates can be coalesced
 and leverage documentFragment or innerHTML.
 e.g.

 VerticalPanel vp = ...
 vp.add(new Label())
 vp.add(new Label())

 The objects are constructed, but the HTML mutations are deferred/queued.
 When adding a DOM mutation to the queue, you could check if existing queue
 data isOrHasChild the new DOM mutation element, and if so, just modify the
 queue element (coalesce) rather than appending another queue item. Then,
 when processing the queue, you only need to add the roots to the DOM,
 attaching/modifying enmasse.

 This would preserve the OO-ness of constructing widget hierarchies without
 requiring 'foreign' string-based templating.

 -Ray


  On Wed, Sep 2, 2009 at 5:13 PM, Bruce Johnson br...@google.com wrote:

  On Wed, Sep 2, 2009 at 6:07 PM, Scott Blum sco...@google.com wrote:

 I do agree with John that we should really discuss how this can be
 implemented.


 It's already implemented!


  Is there some magic trick to make the browser execute a piece of code
 at the time you want, or do we need to go and modify all our event code
 (like with the global uncaught exception handler)?


 No trick, it's as bad as you'd hope it wasn't. On the positive side, it's
 already been done -- I'm just augmenting the tests for the various
 subsystems such as RequestBuilder and event dispatching to make sure we
 tighten the correctness noose as much as possible.

 Longer term, Bob and I both would really like to find a general mechanism
 for making this pattern easy to do from any path into a GWT module from the
 outside, exactly along the lines of what Matt was talking about. I think
 rolling this functionality into gwt-exporter (and then rolling that sort of
 functionality directly into GWT proper) will get us pretty far down the
 road.

 Code review request forthcoming, possibly tomorrow.

 -- Bruce





 


--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-03 Thread Joel Webber
++(++Ray)
Anything we can do to sensibly get this crap out of .user and into .core (or
some other common location) would be very, very good.
If, as a side-effect, we could get DeferredCommand to *not* use
IncrementalCommand (the latter brings in fairly significant dependencies
that are enough to matter for small apps), that would be even better.

On Thu, Sep 3, 2009 at 4:46 PM, Scott Blum sco...@google.com wrote:

 ++Ray.


 On Thu, Sep 3, 2009 at 4:38 PM, Ray Ryan rj...@google.com wrote:

   The mechanism is just brilliant. I have reservations about the api.

 bikeshed
 it seemed kinda nice to have one less type

 Except that we have one more type, BatchedCommand, which looks exactly
 like Command, except with a different name, and you have to subclass it
 rather than implement it...

 A simple thing we could do is:

- create com.google.gwt.core.client,
- change com.google.gwt.user.client.Command to extend the new one
- deprecate com.google.gwt.user.client.Command
- And have BatchedCommand accept com.google.gwt.core.client

 And the two names, DeferredComand and BatchedCommand, don't give much
 clue as to which does what. And of course BatchedCommand doesn't actually
 provide any batching service.

 If we were doing all this from scratch, I suspect we would wind up with
 something like this in core (presuming we're happy with IncrementalCommand
 and addPause):

 package com.google.gwt.core.dispatch

 public interface Command {
   void execute();
 }

 public interface IncrementalCommand {
   boolean execute();
 }

 public class PreEventLoopDispatcher {
   public static PreEventLoopDispatcher get(); { ... }

   public void addCommand(Command c);
 }

 public class PostEventLoopDispatcher {
   public static PostEventLoopDispatcher get(); { ... }

   public void addCommand(Command c);
   public void addCommand(IncrementalCommand c);
   public void addPause();
 }

 Note the avoidance of statics to make commands more testable, a recurring
 subject.

 Seems like we could do this, deprecate the existing classes, and make them
 wrappers around the new.

 /bikeshed

 On Wed, Sep 2, 2009 at 11:36 PM, Ray Cromwell cromwell...@gmail.comwrote:


 Could this also be used as a general pattern to batch DOM updates from
 multiple Widgets performing updates? e.g. a current approach to avoid the
 overhead, of say, installing a dozen widgets, is to concatenate all the HTML
 together, slam it into innerHTML, and then wrap the widgets around the HTML.
 But this rather breaks the nice OO design people are used to with widgets.
 Templating is an alternative, but I'm wondering, why can't we make all of
 the attachment stuff happen via a batch queue. A special optimizer on the
 queue could even recognize instances of when DOM updates can be coalesced
 and leverage documentFragment or innerHTML.
 e.g.

 VerticalPanel vp = ...
 vp.add(new Label())
 vp.add(new Label())

 The objects are constructed, but the HTML mutations are deferred/queued.
 When adding a DOM mutation to the queue, you could check if existing queue
 data isOrHasChild the new DOM mutation element, and if so, just modify the
 queue element (coalesce) rather than appending another queue item. Then,
 when processing the queue, you only need to add the roots to the DOM,
 attaching/modifying enmasse.

 This would preserve the OO-ness of constructing widget hierarchies
 without requiring 'foreign' string-based templating.

 -Ray


  On Wed, Sep 2, 2009 at 5:13 PM, Bruce Johnson br...@google.com wrote:

  On Wed, Sep 2, 2009 at 6:07 PM, Scott Blum sco...@google.com wrote:

 I do agree with John that we should really discuss how this can be
 implemented.


 It's already implemented!


  Is there some magic trick to make the browser execute a piece of code
 at the time you want, or do we need to go and modify all our event code
 (like with the global uncaught exception handler)?


 No trick, it's as bad as you'd hope it wasn't. On the positive side,
 it's already been done -- I'm just augmenting the tests for the various
 subsystems such as RequestBuilder and event dispatching to make sure we
 tighten the correctness noose as much as possible.

 Longer term, Bob and I both would really like to find a general
 mechanism for making this pattern easy to do from any path into a GWT 
 module
 from the outside, exactly along the lines of what Matt was talking about.
 I think rolling this functionality into gwt-exporter (and then rolling that
 sort of functionality directly into GWT proper) will get us pretty far down
 the road.

 Code review request forthcoming, possibly tomorrow.

 -- Bruce








 


--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-03 Thread Bruce Johnson
I like it a lot Ray. (To be completely honest, I knew you were going to say
all that, so I decided to sandbag and let you do the typing :-)

I question if it's really appropriate to explicitly say PreEventLoop and
PostEventLoop considering that...sometimes...the event loop can actually
run re-entrantly. Those names sound like a very strong guarantee that I
don't think we can reliably guarantee. It's more like
PreCurrentJavaScriptStackFullyUnwinding and PostEventLoop.

Actually, to take a step back (which is my very favorite thing to do), there
are several kinds of things that could be consolidated:

1) Single-shot timers
2) Recurring timers
3) Incremental commands that run as soon as possible after the event loop
(faster than setTimeout(0))
4) Incremental commands that run after the event loop via setTimeout(0)
5) Deferred commands that run as soon as possible after the event loop
(faster than setTimeout(0))
6) Deferred commands that run after the event loop via setTimeout(0)
7) Execute-this-before-you-unwind-the-JS-stack-in-which-it-was-enqueued (aka
BatchedCommand)
8) Arguably, runAsync (although it's purpose is so functionally different it
would probalby be a mistake to munge it in)

#3 and #5 might look funny, but it is generally possible to run code *after*
the event loop but *much* sooner than setTimeout(0), which is usually
clamped to some pretty long duration such as 10ms. The reason you wouldn't
want to do #3 and #5 as the default for deferred commands is that it would
keep the CPU overly busy if you did it a bunch in a row. It would very
likely drain mobile batteries quickly, even.

@Ray (or anyone): Can you think of an awesome way to reconcile those behind
a consistent API?







On Thu, Sep 3, 2009 at 4:52 PM, Joel Webber j...@google.com wrote:

 ++(++Ray)
 Anything we can do to sensibly get this crap out of .user and into .core
 (or some other common location) would be very, very good.
 If, as a side-effect, we could get DeferredCommand to *not* use
 IncrementalCommand (the latter brings in fairly significant dependencies
 that are enough to matter for small apps), that would be even better.


 On Thu, Sep 3, 2009 at 4:46 PM, Scott Blum sco...@google.com wrote:

 ++Ray.


 On Thu, Sep 3, 2009 at 4:38 PM, Ray Ryan rj...@google.com wrote:

   The mechanism is just brilliant. I have reservations about the api.

 bikeshed
 it seemed kinda nice to have one less type

 Except that we have one more type, BatchedCommand, which looks exactly
 like Command, except with a different name, and you have to subclass it
 rather than implement it...

 A simple thing we could do is:

- create com.google.gwt.core.client,
- change com.google.gwt.user.client.Command to extend the new one
- deprecate com.google.gwt.user.client.Command
- And have BatchedCommand accept com.google.gwt.core.client

 And the two names, DeferredComand and BatchedCommand, don't give much
 clue as to which does what. And of course BatchedCommand doesn't actually
 provide any batching service.

 If we were doing all this from scratch, I suspect we would wind up with
 something like this in core (presuming we're happy with IncrementalCommand
 and addPause):

 package com.google.gwt.core.dispatch

 public interface Command {
   void execute();
 }

 public interface IncrementalCommand {
   boolean execute();
 }

 public class PreEventLoopDispatcher {
   public static PreEventLoopDispatcher get(); { ... }

   public void addCommand(Command c);
 }

 public class PostEventLoopDispatcher {
   public static PostEventLoopDispatcher get(); { ... }

   public void addCommand(Command c);
   public void addCommand(IncrementalCommand c);
   public void addPause();
 }

 Note the avoidance of statics to make commands more testable, a recurring
 subject.

 Seems like we could do this, deprecate the existing classes, and make
 them wrappers around the new.

 /bikeshed

 On Wed, Sep 2, 2009 at 11:36 PM, Ray Cromwell cromwell...@gmail.comwrote:


 Could this also be used as a general pattern to batch DOM updates from
 multiple Widgets performing updates? e.g. a current approach to avoid the
 overhead, of say, installing a dozen widgets, is to concatenate all the 
 HTML
 together, slam it into innerHTML, and then wrap the widgets around the 
 HTML.
 But this rather breaks the nice OO design people are used to with widgets.
 Templating is an alternative, but I'm wondering, why can't we make all of
 the attachment stuff happen via a batch queue. A special optimizer on the
 queue could even recognize instances of when DOM updates can be coalesced
 and leverage documentFragment or innerHTML.
 e.g.

 VerticalPanel vp = ...
 vp.add(new Label())
 vp.add(new Label())

 The objects are constructed, but the HTML mutations are deferred/queued.
 When adding a DOM mutation to the queue, you could check if existing queue
 data isOrHasChild the new DOM mutation element, and if so, just 

[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-03 Thread Bruce Johnson
Okay, here's a strawman for a new-and-improved proposal. All these would be
in core.
// Deferred command = on the other side of the event loop
interface DeferredCommands {
  public static DeferredCommands get();

  public void add(Command cmd);
  public void add(Command cmd, boolean asap);  // asap = faster than
setTimeout(0)
  public void addPause();
}

// Finally command = before you end the current stack trace
interface FinallyCommands {
  public static FinallyCommands get();

  public void add(Command cmd);
}

// Incremental command = call repeatedly quickly to avoid SSWs
interface IncrementalCommands {
  public static IncrementalCommands get();

  public void add(Command cmd);
  public void add(Command cmd, boolean asap);
}

// Timed command = call based clock time (aka regular old timers)
interface TimedCommands {
  public static TimedCommand get();

  public TimerController scheduleOnce(Command cmd, int millis);
  public TimerController scheduleRecurring(Command cmd, int millis);
}

// Allows optional control over a timer after it's created.
// If the return values in scheduleOnce, etc. aren't used, extra code can
maybe optimize away.
interface TimerController {
  public void pause();
  public void resume();
  public void cancel();
}

I think that maybe consolidating timers into this mix might be a bit much,
but, then again, if we're graduating Command to core, then it seems like
it would be nice to make it the uniform callback interface.

-- Bruce

On Thu, Sep 3, 2009 at 9:28 PM, Bruce Johnson br...@google.com wrote:

 I like it a lot Ray. (To be completely honest, I knew you were going to say
 all that, so I decided to sandbag and let you do the typing :-)

 I question if it's really appropriate to explicitly say PreEventLoop and
 PostEventLoop considering that...sometimes...the event loop can actually
 run re-entrantly. Those names sound like a very strong guarantee that I
 don't think we can reliably guarantee. It's more like
 PreCurrentJavaScriptStackFullyUnwinding and PostEventLoop.

 Actually, to take a step back (which is my very favorite thing to do),
 there are several kinds of things that could be consolidated:

 1) Single-shot timers
 2) Recurring timers
 3) Incremental commands that run as soon as possible after the event loop
 (faster than setTimeout(0))
 4) Incremental commands that run after the event loop via setTimeout(0)
 5) Deferred commands that run as soon as possible after the event loop
 (faster than setTimeout(0))
 6) Deferred commands that run after the event loop via setTimeout(0)
 7) Execute-this-before-you-unwind-the-JS-stack-in-which-it-was-enqueued
 (aka BatchedCommand)
 8) Arguably, runAsync (although it's purpose is so functionally different
 it would probalby be a mistake to munge it in)

 #3 and #5 might look funny, but it is generally possible to run code
 *after* the event loop but *much* sooner than setTimeout(0), which is
 usually clamped to some pretty long duration such as 10ms. The reason you
 wouldn't want to do #3 and #5 as the default for deferred commands is that
 it would keep the CPU overly busy if you did it a bunch in a row. It would
 very likely drain mobile batteries quickly, even.

 @Ray (or anyone): Can you think of an awesome way to reconcile those behind
 a consistent API?







 On Thu, Sep 3, 2009 at 4:52 PM, Joel Webber j...@google.com wrote:

 ++(++Ray)
 Anything we can do to sensibly get this crap out of .user and into .core
 (or some other common location) would be very, very good.
 If, as a side-effect, we could get DeferredCommand to *not* use
 IncrementalCommand (the latter brings in fairly significant dependencies
 that are enough to matter for small apps), that would be even better.


 On Thu, Sep 3, 2009 at 4:46 PM, Scott Blum sco...@google.com wrote:

 ++Ray.


 On Thu, Sep 3, 2009 at 4:38 PM, Ray Ryan rj...@google.com wrote:

   The mechanism is just brilliant. I have reservations about the api.

 bikeshed
 it seemed kinda nice to have one less type

 Except that we have one more type, BatchedCommand, which looks exactly
 like Command, except with a different name, and you have to subclass it
 rather than implement it...

 A simple thing we could do is:

- create com.google.gwt.core.client,
- change com.google.gwt.user.client.Command to extend the new one
- deprecate com.google.gwt.user.client.Command
- And have BatchedCommand accept com.google.gwt.core.client

 And the two names, DeferredComand and BatchedCommand, don't give
 much clue as to which does what. And of course BatchedCommand doesn't
 actually provide any batching service.

 If we were doing all this from scratch, I suspect we would wind up with
 something like this in core (presuming we're happy with IncrementalCommand
 and addPause):

 package com.google.gwt.core.dispatch

 public interface Command {
   void execute();
 }

 public interface IncrementalCommand {
   boolean execute();
 }

 public class 

[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-03 Thread Ray Cromwell
Is there a reason why we just don't add Runnable and CallableV to the JRE
emul and use those instead of Command? This design seems to parallel some of
the patterns in ExecutorService. I could see some of those patterns being
useful (like completion queues, which would be useful for staged
animations).
-Ray


On Thu, Sep 3, 2009 at 7:08 PM, Bruce Johnson br...@google.com wrote:

 Okay, here's a strawman for a new-and-improved proposal. All these would be
 in core.
 // Deferred command = on the other side of the event loop
 interface DeferredCommands {
   public static DeferredCommands get();

   public void add(Command cmd);
   public void add(Command cmd, boolean asap);  // asap = faster than
 setTimeout(0)
   public void addPause();
 }

 // Finally command = before you end the current stack trace
 interface FinallyCommands {
   public static FinallyCommands get();

   public void add(Command cmd);
 }

 // Incremental command = call repeatedly quickly to avoid SSWs
 interface IncrementalCommands {
   public static IncrementalCommands get();

   public void add(Command cmd);
   public void add(Command cmd, boolean asap);
 }

 // Timed command = call based clock time (aka regular old timers)
 interface TimedCommands {
   public static TimedCommand get();

   public TimerController scheduleOnce(Command cmd, int millis);
   public TimerController scheduleRecurring(Command cmd, int millis);
 }

 // Allows optional control over a timer after it's created.
 // If the return values in scheduleOnce, etc. aren't used, extra code can
 maybe optimize away.
 interface TimerController {
   public void pause();
   public void resume();
   public void cancel();
 }

 I think that maybe consolidating timers into this mix might be a bit much,
 but, then again, if we're graduating Command to core, then it seems like
 it would be nice to make it the uniform callback interface.

 -- Bruce

 On Thu, Sep 3, 2009 at 9:28 PM, Bruce Johnson br...@google.com wrote:

 I like it a lot Ray. (To be completely honest, I knew you were going to
 say all that, so I decided to sandbag and let you do the typing :-)

 I question if it's really appropriate to explicitly say PreEventLoop and
 PostEventLoop considering that...sometimes...the event loop can actually
 run re-entrantly. Those names sound like a very strong guarantee that I
 don't think we can reliably guarantee. It's more like
 PreCurrentJavaScriptStackFullyUnwinding and PostEventLoop.

 Actually, to take a step back (which is my very favorite thing to do),
 there are several kinds of things that could be consolidated:

 1) Single-shot timers
 2) Recurring timers
 3) Incremental commands that run as soon as possible after the event loop
 (faster than setTimeout(0))
 4) Incremental commands that run after the event loop via setTimeout(0)
 5) Deferred commands that run as soon as possible after the event loop
 (faster than setTimeout(0))
 6) Deferred commands that run after the event loop via setTimeout(0)
 7) Execute-this-before-you-unwind-the-JS-stack-in-which-it-was-enqueued
 (aka BatchedCommand)
 8) Arguably, runAsync (although it's purpose is so functionally different
 it would probalby be a mistake to munge it in)

 #3 and #5 might look funny, but it is generally possible to run code
 *after* the event loop but *much* sooner than setTimeout(0), which is
 usually clamped to some pretty long duration such as 10ms. The reason you
 wouldn't want to do #3 and #5 as the default for deferred commands is that
 it would keep the CPU overly busy if you did it a bunch in a row. It would
 very likely drain mobile batteries quickly, even.

 @Ray (or anyone): Can you think of an awesome way to reconcile those
 behind a consistent API?







 On Thu, Sep 3, 2009 at 4:52 PM, Joel Webber j...@google.com wrote:

 ++(++Ray)
 Anything we can do to sensibly get this crap out of .user and into .core
 (or some other common location) would be very, very good.
 If, as a side-effect, we could get DeferredCommand to *not* use
 IncrementalCommand (the latter brings in fairly significant dependencies
 that are enough to matter for small apps), that would be even better.


 On Thu, Sep 3, 2009 at 4:46 PM, Scott Blum sco...@google.com wrote:

 ++Ray.


 On Thu, Sep 3, 2009 at 4:38 PM, Ray Ryan rj...@google.com wrote:

   The mechanism is just brilliant. I have reservations about the api.

 bikeshed
 it seemed kinda nice to have one less type

 Except that we have one more type, BatchedCommand, which looks exactly
 like Command, except with a different name, and you have to subclass it
 rather than implement it...

 A simple thing we could do is:

- create com.google.gwt.core.client,
- change com.google.gwt.user.client.Command to extend the new one
- deprecate com.google.gwt.user.client.Command
- And have BatchedCommand accept com.google.gwt.core.client

 And the two names, DeferredComand and BatchedCommand, don't give
 much clue as to which does what. And of course BatchedCommand doesn't
 

[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-02 Thread Scott Blum
Generally speaking I like the idea.  I do agree with John that we should
really discuss how this can be implemented.  Is there some magic trick to
make the browser execute a piece of code at the time you want, or do we need
to go and modify all our event code (like with the global uncaught exception
handler)?

--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---



[gwt-contrib] Re: New API proposal: BatchedCommand

2009-09-02 Thread Bruce Johnson
On Wed, Sep 2, 2009 at 6:07 PM, Scott Blum sco...@google.com wrote:

 I do agree with John that we should really discuss how this can be
 implemented.


It's already implemented!


  Is there some magic trick to make the browser execute a piece of code at
 the time you want, or do we need to go and modify all our event code (like
 with the global uncaught exception handler)?


No trick, it's as bad as you'd hope it wasn't. On the positive side, it's
already been done -- I'm just augmenting the tests for the various
subsystems such as RequestBuilder and event dispatching to make sure we
tighten the correctness noose as much as possible.

Longer term, Bob and I both would really like to find a general mechanism
for making this pattern easy to do from any path into a GWT module from the
outside, exactly along the lines of what Matt was talking about. I think
rolling this functionality into gwt-exporter (and then rolling that sort of
functionality directly into GWT proper) will get us pretty far down the
road.

Code review request forthcoming, possibly tomorrow.

-- Bruce

--~--~-~--~~~---~--~~
http://groups.google.com/group/Google-Web-Toolkit-Contributors
-~--~~~~--~~--~--~---