Support for node status list and duration

Perhaps we should redefine what a node status is.

Based on your messages, there's a need to separate static statuses from ephemeral statuses.

I'll try to define them with an example:

  • static: connection status with the broker, database, etc.
  • ephemeral: related to message processing

If we separate them, we can consider that ephemeral statuses are purely debugging (visually see the process) and therefore do not trigger a change in the status node. This ephemeral status will restore the initial status at the end of duration.

2 Likes

That’s a better version of what I was trying to say :slight_smile:

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.

Introduction of Ephemeral Status:

Definition:

An ephemeral status is a purely virtual; the runtime will only send the status to the editor if at least one editor is open. A user must therefore have their editor open to trigger these ephemeral statuses.
These statuses are not saved/retained; closing and reopening the editor will not cause the previously present ephemeral status to appear.
As its name suggests, the status has a limited lifespan. Once the duration defined or by default is expired, the status will clear or display the last static status if there.

Design:

I propose keeping the node.status method and setting the ephemeral property to true to make this status ephemeral.
The type will therefore be:

type NodeStatusFill = "red" | "green" | "yellow" | "blue" | "grey";
type NodeStatusShape = "ring" | "dot";

// The static status
interface NodeStatus {
fill?: NodeStatusFill;
shape?: NodeStatusShape;
text?: string;
}

// The ephemeral status
interface EphemeralNodeStatus {
fill?: NodeStatusFill;
shape?: NodeStatusShape;
text?: string;
duration?: number;
ephemeral: true;
}

// Node object
status(status: string | NodeStatus | EphemeralNodeStatus): void;

Outstanding questions:

  • What is the default duration of the ephemeral status if duration is not set?
  • Allow duration for static status? At the end of duration the status is cleared.
  • Handle a list of statuses; only for ephemerals?
    status(status: string | NodeStatus | Array<NodeStatus | EphemeralNodeStatus>): void;
    

Do you have any other comments? I would like to move forward with this feature because it would simplify my nodes; I don't have to code this logic myself.

If the concept is validated, I can start looking at how to implement it.

Looks good.

5 Seconds? Or what is the default for the notification display? Set it the same as that?

To be honest, you don't really need the ephemeral flag do you? Just use the duration. If it is set to a number, the status is ephemeral. Otherwise, it is not.

What problem does that address?

I agree, I can think of some uses for this.

Just my 2 cents;

  1. 2 or 3 seconds. Steve's gif gives enough time to read the ephemeral staus and it should not hold up the progress of the node
  2. Keep the current status as is. If it were to be cleared, for example the 'connected' status of an MQTT node, would disappear
  3. Current status handling as is. Why would a list of ephemeral statuses be required. Most would revert to current status. If a 2nd ephemeral status is required to revert to a previous ephemeral status reissue or update to previous.

I also like the way Steve displayed the ephemeral status in italics so it can be distinguished from the current status

1 Like

For this point, I want to simplify the following:

// From
node.status({ text: "custom" })
setTimeout(function() { node.status({}) }, 500)

// To
node.status({ text: "custom", duration: 500 })

If statuses are static, it is rare to have a predefined list of statuses; it would rather be ephemeral.

The duration principle for static and ephemeral statuses is different:

  • Static: The end of the duration clears the status
  • Ephemeral: The end of the duration displays the last static status
2 Likes

Yes, but for some nodes the duration is indefinite (while the flow is running) so what would change?

Exactly, so why would a list be required?

If the duration is not set, the status remains indefinitely. If the duration is set, the status is cleared at the end of the duration.

This is the reason for my question, for me, the list should be used only for ephemeral statuses.

So, let's take an example: I have the status "connected" and a message arrives and I want to display "Querying" then "Querying." then "Querying.." then "Querying..." and then the ephemeral status changes to the static status, which gives:

node.status([
  { text: "Querying", ephemeral: true, duration: 250 },
  { text: "Querying.", ephemeral: true, duration: 250 },
  { text: "Querying..", ephemeral: true, duration: 250 },
  { text: "Querying...", ephemeral: true, duration: 250 },
])
1 Like

… I think it should revert to whatever the static status was previously.

Also what is the maximum time for ephemeral ? If someone sets it to (say) 5 minutes by mistake - does an incoming static status remove it ? If you had a list stacked up is the new static status added to the end - or just clear them all ?

imho I think a list is overthinking it. This is supposed to be a debug aid - what is the benefit of animating things like Waiting. .. …

2 Likes

There is no point in a static status returning to what it was because in that case it becomes ephemeral. I'm trying to find an example that might need it but I can't find one.

I would say yes, regardless of whether it is a static or ephemeral status, the incoming will replace the current status.

We can keep things simple; start without a list and see if there is a need in the future :slightly_smiling_face:

1 Like

I agree with Dave here.

If I have a status like the above, I may well want a short duration override to that but I would certainly want it to go back to the non-ephemeral status afterwards. Perhaps a flag could be used to override that default but it certainly should be the default.

I agree.

:+1:

Thinking back to my nodes, the query can fail and the status returns an error. It's worth creating a temporary status that reverts to the previous one. Here, what matters is triggering the status node (because this is not the case for ephemeral status).

The question now is how to create a duration that reverts and another that clears?

@GogoVega I don't like the ephemeral flag because I will have to simulate the code to determine the previous status, when:

  • I haven't touched the code for a while
  • new maintainers that didn't write the code
  • the status transitions are dynamic

Therefore, my proposal is:

A callback can be provided when duration is set.

node.status({ text: 'foo', duration: 3000, ()=> 'bar'})

When reading the above line, I don't need to spend time interpreting previous lines of code determine that foo transitions to bar after 3000 milliseconds.

If a callback is not provided, the status is cleared.

node.status({ text: 'foo', duration: 3000})

When reading the avove line, it is clear that the status is cleared after 3000 miliseconds.

Very briefly put: an ephemeral status is purely visual, it does not trigger the status node and is only sent to connected editors (no retain mechanism). Of course ephemeral = limited in time.

The point to clarify is regarding the static status (the current one); if duration is defined two behaviors are desired when the duration end:

  • clear the status
  • restore the previous
1 Like

That's the idea behind the list, but as Dave pointed out, it complicates things, and in practice, statuses aren't predefined.

Now, if you have other ideas/comments, I'm open to them :wink:

Could you write a code example to let me better understand this statement, please?

If I take my nodes as an example:

When the database connects, the node's status is connected. This status is static.

Now a message arrives and a query is made. I'd like to create a visual status that indicates querying.... When the query is finished, I'd like to create a visual status query done lasting 200 ms, which then returns to connected.

// db connected
node.status({ text: "connected" })
// incoming message
node.status({ text: "querying...", ephemeral: true }) // default duration - don't matter
// finally
node.status({ text: "query done", ephemeral: true, duration: 200 })
// for error
// here I would like to revert to `connected` after 5s - trigger the status node is maybe the best practice
node.status({ text: "error", duration: 5000 })

As I said, it's rare to have predefined statuses because you don't know the result of your process. The silly example I took is the following:

node.status([
  { text: "Querying", ephemeral: true, duration: 250 },
  { text: "Querying.", ephemeral: true, duration: 250 },
  { text: "Querying..", ephemeral: true, duration: 250 },
  { text: "Querying...", ephemeral: true, duration: 250 },
])

Or your process is dumb and comes back to saying I receive a message... you will never have the example above. wait 5s then wait 4s... is... an exception :smiling_face_with_horns:

1 Like

I don't think that would be right to be honest. I doubt I would want a status node to be triggered just because I am reverting back to a previous status, only if I send a new status (even if it is the same as the previous one).