Alternative to Expression and Script for comparing 2 vars?

Post your feature requets for new triggers, conditions, actions and other improvements.

Moderator: Martin

Locked
kosamja
Posts: 9
Joined: 30 Nov 2017 11:08

Alternative to Expression and Script for comparing 2 vars?

Post by kosamja » 25 Apr 2018 10:41

I just stumbled upon this bug: viewtopic.php?f=5&t=7241
Because of blocking it prevents other flows from running correctly. Is there alternative to Expression and Script to compare 2 variables to avoid blocking? If not can you add any alternative option?

User avatar
Desmanto
Posts: 2709
Joined: 21 Jul 2017 17:50

Re: Alternative to Expression and Script for comparing 2 var

Post by Desmanto » 25 Apr 2018 17:45

This limitation (not a bug anymore) only occured when you have a script that takes so long to finish. Example you are doing millions of loop using older phones; it will takes several seconds to complete. If you use a very long sleep() inside script, it is better to split it out to a sleep action rather than putting it inside the script. Redesign your script structure will be a better alternative rather than locking up the whole script/expression from other flows.

But it can have different solution for different usage case. What kind of script that has delayed other flow? Maybe we can optimize that part. Sometimes I revisit my working flow, just to find ways to shorten or optimize the flow.
Index of Automagic useful thread List of my other useful posts (and others')
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.

kosamja
Posts: 9
Joined: 30 Nov 2017 11:08

Re: Alternative to Expression and Script for comparing 2 var

Post by kosamja » 25 Apr 2018 21:56

if its limitation and not a bug then adding action and condition for comparing 2 variables would be a partial solution to make this limitation less noticeable. In my case am using inside script action while loop to update every 1 second global variable displayed in widget (time that has passed since receiving call up until call ends - for something like simple call screen)


while (existsFile(global_external_storage_dir + "/call_state_ended") == false)
{
sleep(1000);
local_elapsed_seconds = (getDate() - local_start_time)/1000;
local_hours = (local_elapsed_seconds/60)/60;
local_minutes = (local_elapsed_seconds - local_hours*60*60)/60;
local_seconds = local_elapsed_seconds - local_hours*60*60 - local_minutes*60;
if (local_hours < 10)
{
local_hours = ":0" + local_hours;
local_hours = right(local_hours, length(local_hours) - 1);
}
if (local_minutes < 10)
{
local_minutes = ":0" + local_minutes;
local_minutes = right(local_minutes, length(local_minutes) - 1);
}
if (local_seconds < 10)
{
local_seconds = ":0" + local_seconds;
local_seconds = right(local_seconds, length(local_seconds) - 1);
}
local_time_format = local_hours + ":" + local_minutes + ":" + local_seconds;
global_elapsed_time = local_time_format;
}

User avatar
Desmanto
Posts: 2709
Joined: 21 Jul 2017 17:50

Re: Alternative to Expression and Script for comparing 2 var

Post by Desmanto » 27 Apr 2018 17:14

Oh, you have loop inside widget. I know it too, since I also have my mifi graph widget updated per second (with 600 ms script execution time). So if I activate the flow, there is only 400 ms left persecond to execute other flow. So I must make sure I don't have any critical flow running when I am using the graph widget.

Your problem still can be mitigated by moving the sleep outside. But first, it seems you are trying to implement the time format by yourself. Just use the automagic built-in dateformat to parse the date to the format you want. If you need to show the duration in HH:mm:ss format, just use UTC timezone as the base, your time will always be correct. (You can find more about the date pattern at the script or you can check the direct link at my index).

Code: Select all

while (existsFile(global_external_storage_dir + "/call_state_ended") == false)
{
  sleep(1000);
  local_elapsed_seconds = getDate() - local_start_time;

  local_time_format = "{local_elapsed_seconds,dateformat,timezone,UTC,HH:mm:ss}";
  global_elapsed_time = local_time_format;
}
Then let's try to remove the sleep(1000) and put it outside of the script. You can start by putting the condition to check into another temporary variable. And then remove the sleep().

Code: Select all

check  = existsFile(global_external_storage_dir + "/call_state_ended") == false;
while (check)
{
  local_elapsed_seconds = getDate() - local_start_time;

  local_time_format = "{local_elapsed_seconds,dateformat,timezone,UTC,HH:mm:ss}";
  global_elapsed_time = local_time_format;
}
Add a new condition expression after this script, put

Code: Select all

check
Yes, only check, just like that. Since check will always evaluated to true or false. True go to Action Sleep 1 second, false continue to the branch you need. The sleep 1 second loops back to the script. The reason why we put the condition to a temporary variable check, is so we don't have to reevaluate again in the expression, making the script much-much shorter. (only check)

At the beginning, you have 1 script only, and suffered from the global script lock forever.
In the end, you have 1 script, 1 expression and 1 action sleep which loopback to the script. You only suffer unnoticeable 4 ms script lock every seconds (since script usually takes around 4 ms to finish).
In Automagic EAP 1.35.0, you don't have to put the sleep outside. But it is still a good practice to separate out the sleep, especially when it is looped.

========================
Separate global lock
As for me, even though your problem is solved (hopefully), mine is not. If my widget update speed somehow require more than 1 seconds to complete, I will suffer from forever global script lock. I here then request a checkbox in the script, where we can exclude only that particular script from the global script lock. So that script will execute in parallel with another script in another flow. There will be a warning telling us that "we must have make sure that script is not modifying any glovar or doing any I/O or conflicting function to other flow". Another extra warning "enabling the separate global lock can cause chaos".

I am not sure if this is a good idea. But some of us probably have a forever running flow to update a widget info per seconds. If that script is always running, that means we have forever global lock. Since most likely that script only modify 1 widget only, I think is OK to include this "separate global lock" only for that script; of course as long as we have designed the flow properly. Maybe also add another extra option to list out any script which have this option enabled, so we can immediately check them when problems caused by this "separate global lock".
Index of Automagic useful thread List of my other useful posts (and others')
Xiaomi Redmi Note 5 (whyred), AOSP Extended v6.7 build 20200310 Official, Android Pie 9.0, Rooted.

Locked