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

fix: prevent expressions from recomputing more than once #1154

Merged
merged 3 commits into from
Apr 17, 2024

Conversation

Skaiir
Copy link
Contributor

@Skaiir Skaiir commented Apr 16, 2024

Closes #1151

@bpmn-io-tasks bpmn-io-tasks bot added the needs review Review pending label Apr 16, 2024
@Skaiir Skaiir force-pushed the 1151-batch-expression-field-evaluation branch from 1fca212 to 98f4159 Compare April 16, 2024 09:49
@Skaiir Skaiir changed the title fix: use lodash equality in expression fields fix: prevent expressions from recomputing more than once Apr 16, 2024
@Skaiir Skaiir force-pushed the 1151-batch-expression-field-evaluation branch from 98f4159 to 7519fdb Compare April 16, 2024 09:57
@Skaiir Skaiir force-pushed the 1151-batch-expression-field-evaluation branch from 7519fdb to 4bebb52 Compare April 16, 2024 10:18
@vsgoulart
Copy link
Contributor

@Skaiir Please check why the Carbonisation test is failing

@Skaiir Skaiir requested a review from vsgoulart April 16, 2024 17:04
@Skaiir
Copy link
Contributor Author

Skaiir commented Apr 16, 2024

@vsgoulart It's the tasklist carbonisation that's failing because they are out of sync following the UX changes during spring cleaning.

Comment on lines +13 to +14
eventBus.on('import.done', this.reset.bind(this));
eventBus.on('reset', this.reset.bind(this));
Copy link
Contributor

Choose a reason for hiding this comment

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

So are we saying here:

Expression fields will not recompute unless

  1. A field with shouldNotRecompute: false | null | undefined is updated
  2. The form is reloaded
  3. The form is reset

Copy link
Contributor Author

@Skaiir Skaiir Apr 17, 2024

Choose a reason for hiding this comment

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

Basically yes, the idea being that we only want expressions to compute once when a change has happened, except if that change was triggered by an expression (in which case we ignore it).

Basically, that makes a change (say a form field value is set) propagate through every expression at most once, preventing them from re-evaluating in loops.

Ideally in the future, we don't have to do any of this sillyness when we separate view and model, but for now it was the best way I found to get around the looping issue entirely within the constraints. It's also why I built it as a module, so that it can be easily extracted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

With this system, loops will still loop (they will advance one step per value change). But we are happy having loops be undefined behavior in general, as they are faulty configs. Like you mentioned, linting would be great, but it's 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.

Note this does not prevent expressions from chaining, however it does give a certain top to bottom precedence to how they evaluate if the dependency graph has cycles. But again, if they do have cycles it's considered undefined behavior and not something we should care about.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's fine. I am ok with making loops only run once on a change. I do agree that we should separate out the model and the view but that's too big of a change for a fix.

Comment on lines +2 to +26
"components": [
{
"computeOn": "change",
"type": "expression",
"id": "Field_exprA",
"key": "exprA",
"expression": "=exprB + 10"
},
{
"computeOn": "change",
"type": "expression",
"id": "Field_exprB",
"key": "exprB",
"expression": "=exprA * 2"
}
],
"type": "default",
"id": "Form_cyclic_example",
"executionPlatform": "Camunda Cloud",
"executionPlatformVersion": "8.5.0",
"exporter": {
"name": "Camunda Modeler",
"version": "5.22.0"
},
"schemaVersion": 16
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there some way to creating a linting rule that warns the user about this cyclical reference?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes there is, but it involves building up an object graph of all the feel expressions, the various local variable contexts, ect... Not having a separated model and view makes this extra difficult and not something I think warrants the time investment.

Copy link
Contributor

@vsgoulart vsgoulart left a comment

Choose a reason for hiding this comment

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

To me it looks ok, but please check Douglas' comments before merging

@Skaiir Skaiir merged commit 1316d19 into main Apr 17, 2024
10 of 12 checks passed
@Skaiir Skaiir deleted the 1151-batch-expression-field-evaluation branch April 17, 2024 14:17
@bpmn-io-tasks bpmn-io-tasks bot removed the needs review Review pending label Apr 17, 2024
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