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

Add ChangeBatcher to plugin for two-way sync #478

Merged
merged 20 commits into from
Oct 18, 2021
Merged

Add ChangeBatcher to plugin for two-way sync #478

merged 20 commits into from
Oct 18, 2021

Conversation

kennethloeffler
Copy link
Member

@kennethloeffler kennethloeffler commented Sep 20, 2021

Closes #294, #368, and #433.

Depends on changes from rojo-rbx/rbx-dom#210.

This PR implements ChangeBatcher. Its job is to collect any instance changes and periodically try to turn them into a patch to send to the Rojo server. Right now, this happens every 200ms.

There is one small bump I hit during implementation. When a change is made to the Source property of script, AND the change is made from a script or the command bar, AND the script is open in Studio, the Changed event fires three times for Source. The first event occurs right when the change is made (or, if deferred events are enabled, at the next invocation point), while the latter two events occur some time after the current Heartbeat cycle.

If this is left unchecked, the ChangeBatcher detects a spurious change to Source after a patch application. To fix it, I added InstanceMap:pauseInstanceForBatch. It pauses an instance until the ChangeBatcher decides to unpause it (in this case, after the next Heartbeat cycle). This isn't terribly consequential - it just causes the client to send an unnecessary write request. I'm not 100% on whether we should keep this mechanism or not.

I also made InstanceMap:pauseInstance no longer take a callback and added InstanceMap:unpauseInstance to avoid having to create a closure for every set of property updates during patch application.

@kennethloeffler kennethloeffler marked this pull request as ready for review September 20, 2021 21:20
@kennethloeffler kennethloeffler changed the title Add ChangeBatcher for two-way sync Add ChangeBatcher to plugin for two-way sync Sep 21, 2021
@kennethloeffler
Copy link
Member Author

It's more or less where I want it for now - any further revisions are welcome

I probably should have done this in the first place...

ChangeBatcher still needs to unpause instances, but we don't need to
hold pauses for any longer than one cycle.
@kennethloeffler
Copy link
Member Author

For some reason I had it in my head that RunService.RenderStepped throws when used on Roblox Studio's server mode - but I just checked and it does not!

Copy link
Contributor

@LPGhatguy LPGhatguy left a comment

Choose a reason for hiding this comment

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

Looking really good! Left a couple comments.

@LPGhatguy LPGhatguy merged commit 9d0b313 into rojo-rbx:master Oct 18, 2021
@kennethloeffler kennethloeffler deleted the two-way-sync-changebatcher branch October 19, 2021 22:12
Dekkonot pushed a commit to UpliftGames/rojo that referenced this pull request Jan 11, 2024
* Implement ChangeBatcher

* Use ChangeBatcher for two-way sync

* Pause updates during patch application

* I can English good

* Break after encountering a nil Parent change

This prevents __flush from erroring out when an instance's Parent is
changed to nil and it has other property changes in the same batch.

* Update rbx_dom_lua

* Don't connect changed listeners in a running game

 rojo-rbx#468 made me realize how bad of an idea this is in general...

* Update TestEZ and fix sibling Ref reification test

* Add ChangeBatcher tests

* Test instance unpausing by breaking functionality out to __cycle

* Break up the module a bit and improve tests

* Shuffle requires around and edit comment

* Break out more stuff, rename createChangePatch -> createPatchSet

* Make ChangeBatcher responsible for unpausing all paused instances

This somewhat improves the situation (of course, it would preferrable
to not have to hack around this problem with Source at all). It also
sets us up nicely if we come across any other properties that do
anything similar.

* Remove old reference to pausedBatchInstances

* Use RenderStepped instead of Heartbeat and trash multi-frame pauses

I probably should have done this in the first place...

ChangeBatcher still needs to unpause instances, but we don't need to
hold pauses for any longer than one cycle.

* Remove useless branch

* if not next(x) -> if next(x) == nil

* Add InstanceMap:unpauseAllInstances, use it in ChangeBatcher

* Move IsRunning check to InstanceMap:__maybeFireInstanceChanged
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.

Debounce instance property changes
2 participants