Comet fixes

This fixes a handful of bugs that when taken together kept things mostly working!

  - Unify lastListenerTime (which was previously always zero) with
    lastListenTime
  - Make lastRenderTime, delta timestamps, and lastListenerTime
    consistent with each other as they are directly compared
  - More accurately track whether any deltas have been sent
  - Pretend initial render happened at creation time to prevent a second
    render call from running on the initial Listen message
  - Rename devMode to alwaysReRenderOnPageLoad
It's actually the initial render that's the problem (although we're also
using a random name for the reasons you mention). The comet snippet
constructs the comet actor (which includes sending any messages to the
actor that have been queued up by `LiftSession.sendCometActorMessage`) and
requests an initial render via `AskRender`. If any of those queued messages
triggers a partial update (or alternatively if a partial update sneaks in
between construction and sending the `AskRender` message [something else
we've seen...]), they'll be lost.

Re `partialUpdateStream_?`, the key changes aren't to partial update
processing per se, but the response to the `Listen` message and making sure
not to clear partial updates in the private `performReRender` method
(see d5fecefc for the specific changes).



On Wed, Dec 3, 2014 at 5:27 PM, Antonio Salazar Cardozo <
notifications@github.com> wrote:

> In web/webkit/src/main/scala/net/liftweb/http/CometActor.scala:
>
> > @@ -474,12 +479,32 @@ trait CometActor extends LiftActor with LiftCometActor with CssBindImplicits {
> >     */
> >    def lastListenerTime: Long = _lastListenerTime
> >
> > +  def lastRenderTime: Long =  _lastRenderTime
> > +
> > +  /**
> > +    * If this method returns true, this CometActor will be treated as a source
> > +    * of continuous partial updates. Usually the basic assumption of a Lift
> > +    * Comet Actor is that render will display the current state of the actor.
> > +    * Partial updates may modify that display, but it is always possible to
> > +    * recreate the complete display by calling render again (in which case
> > +    * pending partial updates can be safely discarded). If this method
> > +    * returns true, render will not be called, but partial updates are
> > +    * guaranteed to always be sent to the client. This is useful as a means to
> > +    * push arbitrary JavaScript to the client without a distinct UI for the
> > +    * comet actor itself.
> > +    */
> > +  protected def partialUpdateStream_? : Boolean = false
>
> Hmm… I guess what I'm saying is that partialUpdate can only not be relied
> on if reRender is used or the same comet is sent down on another page. Is
> that the situation you're concerned about?
>
> I'm asking because I've used comets in the way you describe and not really
> run into the issue you're describing, but when I use comets solely for
> partial updates I always use random names for them, so they're never
> rendered beyond the initial render. At that point, partial updates should
> never get discarded wholesale (timing bugs like the other ones you've
> described notwithstanding).
>
> As for copying—it seems like just refactoring would be an option?
> mediumPriority and highPriority are available as handlers for dealing
> with partialUpdate different in a subclass as needed; I believe both are
> tested before CometActor's internal handling is attempted.
>
> —
> Reply to this email directly or view it on GitHub
> <https://github.com/lift/framework/pull/1619/files#r21243212>.
>