Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comet Rehydration #1770

Merged
merged 21 commits into from
Dec 14, 2017
Merged

Comet Rehydration #1770

merged 21 commits into from
Dec 14, 2017

Conversation

joescii
Copy link
Contributor

@joescii joescii commented Feb 14, 2016

As discussed on this ML thread, comet rehydration is another step towards supporting Lift server instance failover.

This feature is DISABLED by default. It can be enabled with these two lines in Boot:

LiftRules.redirectAsyncOnSessionLoss = false
LiftRules.noCometSessionCmd.default.set(() => JsCmds.Run("lift.rehydrateComets()"))

Rehydrating comets works by refetching the html from the Lift server. The html is slapped into an iframe and scraped for the comet GUID and version pairs. The toWatch is replaced with the new comet pairs effectively allowing the newly created comets to take over.

As with the LiftRules.putAjaxFnsInContainerSession PR, this feature can be exercised with this project but using the /comet page.

@joescii joescii added this to the 3.1 milestone Feb 14, 2016
@joescii
Copy link
Contributor Author

joescii commented Feb 14, 2016

I vote for marking codacy's complaint about cyclomatic complexity as WONTFIX.

@farmdawgnation
Copy link
Member

Hey @joescii - what are your thoughts on the stability of this? Is this something that could potentially be included in 3.1 or nah?

@Shadowfiend
Copy link
Member

Going to drop the milestone here. We can restore it when timelines are a little clearer, I think.

@Shadowfiend Shadowfiend removed this from the 3.1.0-RC1 milestone Jun 12, 2017
@farmdawgnation
Copy link
Member

@joescii I see you've been periodically merging master here. LMK When you think it's ready for review/ testing

@joescii joescii changed the title [WIP] Comet Rehydration Comet Rehydration Oct 3, 2017
if (!dataType) {
dataType = "script";
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Shadowfiend This is the change I was talking about in this ML thread https://groups.google.com/forum/#!topic/liftweb/KdH4kgZ-5ug

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because Javascript, this change is backward compatible. I don't think we have to worry too much about this change so long as the dataType check works as we expect.

Copy link
Member

@farmdawgnation farmdawgnation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have some changes to request, but it looks promising!

iframe.appendChild(doc);
doc.innerHTML = html;

toWatch = {};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this attached to window or a lift object on the window?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's declared up at the top at line 20

restartComet();

// Under the impression that a parentless node needn't be deleted.
// It should be a candidate for GC after it goes out of scope
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is right. We should be able to remove this comment.

}
function onFailure(err) {
// Try again??
settings.logError(err);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we fall back to the classic comet refresh method? (Reloading the page?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we should hard code a refresh here, or make it a LiftRules setting?

cometActor.parentTag.copy(child = cometHtml) % ("id" -> containerId)
private [this] def buildContainer(cometHtml: NodeSeq, cometActor: LiftCometActor, containerId: String): NodeSeq = {
val cometVersion = http.S.requestCometVersions.is
.collectFirst { case CometVersionPair(guid, ver) if guid == cometActor.uniqueId => ver }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please break this into multiple lines for readability.

.collectFirst { case CometVersionPair(guid, ver) if guid == cometActor.uniqueId => ver }
.getOrElse("")

cometActor.parentTag.copy(child = cometHtml) % ("id" -> containerId) % ("data-lift-comet-version" -> cometVersion)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please break this into multiple lines for readability.

var iframe = document.createElement("iframe");
var doc = document.createElement("html");
iframe.appendChild(doc);
doc.innerHTML = html;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a reminder to be very careful about where the html value in this method comes from. My understanding is that our risk here is pretty minor as doc andiframe are never attached to the page, but whenever I see it in a PR I gotta mention it.

(Old habits die hard.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is fundamental to the design of this feature. Essentially we reload the page from Lift, and steal all of the comet IDs from the resulting HTML.

if (!dataType) {
dataType = "script";
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because Javascript, this change is backward compatible. I don't think we have to worry too much about this change so long as the dataType check works as we expect.

Copy link
Member

@farmdawgnation farmdawgnation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took this out for a spin and it worked like a charm!

How would you feel about providing a helper in LiftRules that makes the correct changes to the configuration? Something like...

LiftRules.enableCometRehydration()

What do you think?

Side note: I'd love to ship this next month as a part of 3.2.0-RC1 if you feel comfortable with it.

@Shadowfiend
Copy link
Member

Side note

❗️

@joescii
Copy link
Contributor Author

joescii commented Nov 29, 2017

@farmdawgnation I dig that idea. So basically something like

def enableCometRehydration(): Unit = {
  LiftRules.redirectAsyncOnSessionLoss = false
  LiftRules.noCometSessionCmd.default.set(() => JsCmds.Run("lift.rehydrateComets()"))
}

@farmdawgnation
Copy link
Member

Yup!

@farmdawgnation
Copy link
Member

@joescii Bump! We have about 10 days to get this in for the RC! :)

LiftRules.redirectAsyncOnSessionLoss = false
LiftRules.noCometSessionCmd.default.set(() => JsCmds.Run("lift.rehydrateComets()"))
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@farmdawgnation @Shadowfiend I feel like the hardest part to get right here is the comment...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the comment strikes the right chord overall. The one guidance we might add would be to say that you should code applications depending on this behavior to be able to reconstruct comet state from cookies or from information available from the client (e.g. JS state, state stores, etc)

If you feel like that would be a good addition I say add it. Otherwise, I'm going to approve this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment updated

Copy link
Member

@farmdawgnation farmdawgnation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seal of approval

@farmdawgnation farmdawgnation merged commit ba9c893 into master Dec 14, 2017
@farmdawgnation farmdawgnation deleted the joe-comet-rehydrate branch December 14, 2017 20:32
@farmdawgnation farmdawgnation added this to the 3.2.0-RC1 milestone Dec 14, 2017
@farmdawgnation
Copy link
Member

it's happening

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants