Semaphore blocks switch from resetting


#1

1) Give a description of the problem
I’ve got a number of virtual switches I want to act like buttons - only ever responding to “On” events, and immediately returning to “Off” when triggered.

I’ve written a dedicated piston for the purpose of resetting virtual switches that I wish to act in this way.

However when another piston triggers multiple switches, the piston does not behave correctly, reporting a “Waited on semaphore for 10000ms”

2) What is the expected behaviour?
I expect all switches handled by this piston to toggle back to their previous state

3) What is happening/not happening?
Only one of the buttons toggles back.

**4) Post a Green Snapshot of the piston![image|45x37](![image|690x352]

5) Attach logs after turning logging level to Full
27/05/2021, 19:39:06 +525ms
+1ms ╔Received event [LeviotAutoSwitch].switch = on with a delay of 48ms
+10061ms ║RunTime Analysis CS > 17ms > PS > 10017ms > PE > 27ms > CE
+10062ms ║Piston waited at a semaphore for 10013ms
+10064ms ║Runtime (39793 bytes) successfully initialized in 10017ms (v0.3.113.20210203) (10062ms)
+10065ms ║╔Execution stage started
+10072ms ║║Comparison (enum) on changes_to (string) on = false (1ms)
+10074ms ║║Condition #4 evaluated false (4ms)
+10080ms ║║Condition #5 evaluated false (5ms)
+10087ms ║║Condition #6 evaluated false (6ms)
+10093ms ║║Condition #7 evaluated false (5ms)
+10100ms ║║Condition #10 evaluated false (5ms)
+10101ms ║║Condition group #1 evaluated false (state did not change) (31ms)
+10102ms ║╚Execution stage complete. (37ms)
+10103ms ╚Event processed successfully (10103ms)
27/05/2021, 19:39:06 +802ms
+1ms ╔Received event [LeviotHighSwitch].switch = off with a delay of 51ms
+44ms ║RunTime Analysis CS > 16ms > PS > 5ms > PE > 24ms > CE
+47ms ║Runtime (39705 bytes) successfully initialized in 5ms (v0.3.113.20210203) (45ms)
+47ms ║╔Execution stage started
+57ms ║║Condition #4 evaluated false (6ms)
+60ms ║║Comparison (enum) off changes_to (string) on = false (0ms)
+62ms ║║Cancelling condition #5’s schedules…
+63ms ║║Condition #5 evaluated false (4ms)
+69ms ║║Condition #6 evaluated false (6ms)
+75ms ║║Condition #7 evaluated false (4ms)
+81ms ║║Condition #10 evaluated false (5ms)
+82ms ║║Cancelling condition #1’s schedules…
+82ms ║║Condition group #1 evaluated false (state changed) (31ms)
+84ms ║╚Execution stage complete. (37ms)
+85ms ╚Event processed successfully (85ms)
27/05/2021, 19:39:06 +477ms
+1ms ╔Received event [LeviotHighSwitch].switch = on with a delay of 33ms
+42ms ║RunTime Analysis CS > 12ms > PS > 3ms > PE > 27ms > CE
+45ms ║Runtime (39712 bytes) successfully initialized in 3ms (v0.3.113.20210203) (43ms)
+45ms ║╔Execution stage started
+55ms ║║Condition #4 evaluated false (5ms)
+58ms ║║Comparison (enum) on changes_to (string) on = true (0ms)
+60ms ║║Cancelling condition #5’s schedules…
+61ms ║║Condition #5 evaluated true (4ms)
+62ms ║║Cancelling condition #1’s schedules…
+62ms ║║Condition group #1 evaluated true (state changed) (13ms)
+65ms ║║Cancelling statement #8’s schedules…
+71ms ║║Executed physical command [null].off() (3ms)
+72ms ║║Executed virtual command [LeviotHighSwitch].toggle (5ms)
+75ms ║╚Execution stage complete. (29ms)
+76ms ╚Event processed successfully (76ms)


#2

I seem to have fixed the issue by trying multiple things, I’m not sure if all of these are required but its working, so I’m leaving it like this:

  • setting Piston settings to “Allow Parallelism”
  • setting “With” statement to async
  • setting “With” statement to Allow Multiple
  • setting “With” statement to Never Cancel Tasks

I don’t know if all of these are needed, but it works!


#3

The semaphore wait is webCoRE trying to serialise execution of multiple instances of a piston so they don’t conflict. It is typically a ten second wait. You can end up with events out of sequence if a lot are happening at once as not all will be held.

It is the enable parallelism that prevents the semaphores and it is fine for you because each switch is really being processed independently anyway.