Here's the Lift CometActor code:

// A CometActor that keeps the user updated
class LongTime extends CometActor {
  private var url: Box[String] = Empty
  private var progress: Int = 0

  // a CometActor that has not been displayed for
  // 2 minutes is destroyed
  override def lifespan: Box[TimeSpan] = Full(2 minutes)

  // get messages from the ThingBuilder
  override def highPriority = {
    case BuildStatus(p, Empty) =>
      this.progress = p
      reRender(false)

    case BuildStatus(_, Full(u)) =>
      url = Full(u)
      progress = 100
      reRender(false)
      partialUpdate(RedirectTo(u))
  }

  // start the job
  override def localSetup() {
    ThingBuilder ! this
    super.localSetup()
  }

  // display the progress or a link to the result
  def render =
  url match {
    case Full(where) =>
      <span>Your job is complete.  <a href={where}>Click Me</a></span>
    case _ =>
      <span>We're working on your job... it's {progress}% complete</span>
  }  
}