Order of Operation

Agreed. But … kinda not. Because I think people would always tick it even if they didn’t need it and then would wonder why their workflows were slow.

So I think you can probably make it do this, if you really need, and making it hard is the right thing to do.

3 Likes

Hey @aschofer,

Thanks for the detailed write-up.

I have just one question:
If the recommended way of structuring Backend Workflows that should run synchronously is to utilise Custom Events, how do we then access the Result of that Custom Event?

For instance, I have Backend Workflows with Steps that run in sequence, with each Step requiring the result of the previous Step. Given your input, I should instead have each Step as a Custom Event, to prevent the instant activation of ALL the Steps at one go.

However, with that, I find that I’m unable to use the “Result of Step…” function, which makes things highly inefficient if I have to do a Search for each Step (Correct me if I’m wrong).

Thanks and let me know if what I said was unclear!

cc @jess

3 Likes

Good point - I would at least like having an easy option though, even as a long time user. It’s similar to the data consistency issue - You lose some speed and development time by doing “Schedule API Workflow” instead of “Schedule API Workflow on List”, but with the upside of knowing 100% data AND workflow consistency (since “Schedule API Workflow” actually goes step by step). In some cases, a tradeoff is worth it. :slight_smile: Besides, if I had a dime for every “Result of Step X is not empty” to force a workflow to be more step by step, I’d be sippin rum in Jamaica haha!!

2 Likes

Fantastic point - You can have an input for Custom Event, but the “Result of” (output) for a Custom Event is not an option :frowning: Would be awesome to have.

1 Like

@jess is there any way to identify which actions are server side, client side, or a mix of both?
The explanation is the docs isn’t definitive

This is not a change. This is always how it has been.

3 Likes

Great question! For the most part, actions will run on the server or both. Go to page actions, toggling or scrolling to elements, and setting custom states would be examples of client-side actions. In addition, client-side workflows will not show up in the server logs, so this can be a means to confirm or deny whether an action is client-side. Also happy to add a docs request for our team to add a comprehensive list to the docs for each.

2 Likes

I’m thinking how the action Terminate this workflow (TTW) affects this.

If the TTW has a condition depending on a prior action (A):

  • That means A could be assumed to run before the TTW. Maybe this means all actions prior to the TTW will run before the TTW, or will the TTW be “smart” and only wait for the action it depends on (A)?

  • That would mean no actions post the TTW would run before the TTW’s condition can be checked?

Thinking also about the potentially limited use of Add a pause before next action, since it will not postpone server side actions.

Best, Peter

4 Likes

I learned the hard way that some plugin actions will not follow this order of operation – even when implemented through a Custom Event.

In fact some plugins, when using debugger in step-by-step mode, will appear to comply with this order of operations – but when operating at normal speed will violate the order, potentially creating duplicate workflows that mess everything up.

If your app requires precise workflow order of operations, I recommend avoiding plugin actions within those workflows, and instead sticking with basic bubble functions.

3 Likes

Really? Is that actually happening? That’s terrible :cry:

The trouble here isn’t with the Bubble architecture it is with how we think about synchronous versus asynchronous. All modern web services are built around asynchronous operations, including Bubble. Roughly that means that actions, scheduled workflows, etc… are dispatched at the scheduled time (defaulting to now). However they will wait to run until all their formal dependencies are fulfilled, effectively until all the parameters passed in the call and the conditions are met.

The danger comes in when you are informally passing dependencies such as through states or do a search for. In those circumstances nothing has been formally promised and so the action or workflow says “hey great everything is fulfilled. I’m good to go”.

Long story short in trying to squeeze actions and workflows into being synchronous operations you are asking those, roughly, independent actions and workflows to informally know what each other are doing. If you need action A to know what action B is doing the safe way is to formally create a dependency of A on B through parameter(s).

7 Likes

For anyone who is a visual learner like myself, here is a visual workflow guide I did of the reply from Bubble Support. Any additions or changes you wish to make let me know and I can update it.

*updated June 5 to include @austin3’s suggestion

33 Likes

In this regard what is the best way to set up actions to happen if the actions have to Create OR Update multiples of interdependent data?

I have a lot of workflows where there is one trigger then a series of thing have to happen.

Consider this setup.

Datasets:. Units, invoices. Invoices has a ‘thing’ of units.

Workflow is setup like this:
Step 1. If a unit exists, update it.
Step2. If unit does not exist, create it.
Step3. Do a search for the unit and add it to a search for an invoice.

Based on what is said above, I can’t reliably use the ‘do a search for unit’.

This means that it is possible that the Unit does not get added to the invoice.

The recommendation is to use ‘result of step x’, but we can use that. Because if the unit did not already exist, result of step 1 (update) is nothing, and if it does actually already exist and just needs updating, then the result of step 2 (create) will be nothing.

The User data type is the only type that has ‘return the user if already exists’ on the create operation. In this case it seems to make sense, but I don’t see that for others create operations for other ‘things’.

What would be the recommended setup here?

Appreciate the replies.

2 Likes

@crathbun Just use 2 conditional actions to add the Unit to the invoice:

  1. Update The Unit (if it exists)
  2. Create a Unit (if it doesn’t exist)
  3. Add The Result of step 1 (the Unit) to the invoice (if the result of step 1 is not empty)
  4. Add the result of step 2 (the unit) to the invoice (if the result of step 2 is not empty)
2 Likes

Thanks. I guess that makes sense. Gonna be tricky when there are 3 to 4 layers of this! But thanks.

To make one step dependent on another I just need to put "result of Step x’ Somewhere in the step right?

Let’s assume we’re changing something. Can the "result of step x’ need to be in any of these three areas? Assuming so since to run the step then Bubble would need to make sure all the criteria are met to run the step, but just want to make sure.

image

This was sorely needed, thanks bubble for posting this. I think a lot of the confusion in the replies comes from a gap between how people thought these things worked vs how they actually do. Several months ago I was having some major workflow issues and reached out to support directly. I received back an email with similar information to this post (though less detailed and refined). I was pretty shocked to learn that I had been falsely relying on sequential ordering for the previous 6 months of using bubble. There are a lot of users and apps in a similar boat as @ryanck

I definitely think the bubble team needs to take a survey of how self-explanatory the language of workflows is and how it can be improved, but this is a good start.

One thing I should point out though is that I have been able to consistently and reliably use the “Result of step X” in my workflows to enforce sequentialness when it is needed. @crathbun from my experience you can in fact put this anywhere in the action. You seem to even be able to just throw a “if result of step x is not empty” into the conditional tab to force it to wait, even if you don’t use the result.

@cowontherun thank you for the graphic. For those who are visually minded and are struggling with this, I’d recommend mapping out your workflows in a similar way, with lines indicating workflows that are dependent. Many workflows that seem sequential actually only require 1 or 2 sequential steps, and having the rest run in parallel makes them much faster.

Tldr;
I understand why bubble structured things this way, as they allow for greater speed and flexibility. Thank you for posting this, but I think theres significant work to be done in making the way workflows operate behind the seens easier to figure out intuitively.

5 Likes

I agree. I think the UI utterly fails to convey how things actually work. Execution seems to follow more of a “data-flow” or “data-driven” approach, but one would never intuit that from the current UI design.

Pretty shocked by this information. A ‘workflow’ is sequential by definition. Likewise, using the term ‘step’ implies sequential execution. So it’s no surprise that using these terms for non-sequential actions has created mass confusion.

Suggest you revise the semantics as well as include this information in the foundational learning resources and bootcamp, so that those that come after don’t learn this crucial information only after many months of development, like many of us have done. Think of the countless hours of debugging and head-scratching, that not doing so will have already resulted in? It could really do with an explanatory diagram, as I’m still not sure I understand it properly.

6 Likes

I hope the Bubble team can make workflows display just like the visual document that @cowontherun shared. That would clarify this for new and experienced users. Also would be good to show “the result of” as a step. Ideally the whole inspector could have a setting to expand to full screen as well since both reading and writing complex expressions in those little boxes can be challenging to see and understand what is actually going on.

3 Likes