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

Simulator hangs on startup when existing device file is present #6

Closed
amprim opened this issue Oct 14, 2022 · 9 comments
Closed

Simulator hangs on startup when existing device file is present #6

amprim opened this issue Oct 14, 2022 · 9 comments
Assignees

Comments

@amprim
Copy link

amprim commented Oct 14, 2022

As mentioned in #5.


Issue

When running uhppote-simulator, the simulator hangs when attempting to load config files from a previous run. Neither the REST API or any simulated controllers can be contacted.

Issue encountered on Linux x86_64 (PopOS/Ubuntu 22.04 LTS).

Steps to Reproduce

In a terminal window, run the following to start a uhppote-simulator instance.

./uhppote-simulator --bind 127.0.0.1:60000 --rest 127.0.0.1:8000 --devices /tmp/

In another terminal window, run the following to generate a controller config. (EDIT: Fixed duplicate command)

curl -X POST http://127.0.0.1:8000/uhppote/simulator -H 'Content-Type: application/json' -d '{"device-id": 123456789, "device-type": "UT0311-L04", "compressed": false}'

In the first terminal window, stop and rerun the uhppote-simulator command. It will hang similar to the following. The make targets were setup to make testing easier: simulator checks for and removes a config file prior to running the simulator, while sim does not, just attempts to run the simulator.

amprim@pop-os:~/Projects/access_control$ make simulator
mkdir -p /tmp/devices
./uhppote-simulator --bind 127.0.0.1:60000 --rest 127.0.0.1:8000 --devices /tmp/devices
   ... loading devices from '/tmp/devices'
   ... bound to address '127.0.0.1:60000'

^CFailed to read from UDP socket [read udp 127.0.0.1:60000: use of closed network connection]
make: *** [Makefile:7: simulator] Error 1

amprim@pop-os:~/Projects/access_control$ make sim
./uhppote-simulator --bind 127.0.0.1:60000 --rest 127.0.0.1:8000 --devices /tmp/devices
   ... loading devices from '/tmp/devices'

As you can see, something prevents the simulator from reaching the point of binding to the --bind address.


Thank you in advance for your assistance!

@uhppoted
Copy link
Owner

Hi,

I can't seem to reproduce your problem - when I try this is what I get:

In first terminal:

>> .. running simulator 1
mkdir -p /tmp/devices
./bin/uhppote-simulator --bind 127.0.0.1:60000 --rest 127.0.0.1:8000 --devices /tmp/devices
   ... loading devices from '/tmp/devices'
   ... bound to address '127.0.0.1:60000'

In second terminal:

>> .. running simulator 2
./bin/uhppote-simulator --bind 127.0.0.1:60000 --rest 127.0.0.1:8000 --devices /tmp/devices
   ... loading devices from '/tmp/devices'
Failed to bind to UDP socket [listen udp 127.0.0.1:60000: bind: address already in use]
uhppoted@uhppoted:/opt/uhppoted/uhppote-simulator$ 

Which is as expected - you can't have two simulators running at the same time because they both bind to the same address:port.

Am I missing something?

BTW, Docker may be an easier way to achieve what I think you're trying to do - there's an example here.

@amprim
Copy link
Author

amprim commented Oct 14, 2022

Oh, d'oh! I didn't copy the second command correctly, it's not supposed to be the same as the first. Fixed above, sorry about that!

That said, I just attempted to reproduce this again, and it's started working correctly, at least when I run the commands directly from terminal. Let me do a little more digging and see if I can figure out what triggers this.

@uhppoted
Copy link
Owner

uhppoted commented Oct 14, 2022

Ah, ok - was able to replicate this with your configuration and scripts from Possible issue with time profiles. Just to confirm - these are the steps I followed:

  1. Clean out the tmp folder
rm -f /tmp/123456789.json
  1. Run one copy of the simulator:
./bin/uhppote-simulator --bind 127.0.0.1:60000 --rest 127.0.0.1:8000 --devices /tmp/

>   ... loading devices from '/tmp/'
>   ... bound to address '127.0.0.1:60000'
  1. Run the CLI test program to create a /tmp/123456789.json file:
./test-cli.sh

> 123456789: time profile 3 created
> 123456789: time profile 2 created
> 123456789 154321 true
> 123456789 112345 true
...

  1. Run a second copy of the simulator in a different window:
./bin/uhppote-simulator --bind 127.0.0.1:60000 --rest 127.0.0.1:8000 --devices /tmp/
>    ... loading devices from '/tmp/'

Let me dig into that..

@amprim
Copy link
Author

amprim commented Oct 14, 2022

Yup, that looks right.

I think it may be an issue with either card swipe events, or events in general, being written to/read from the file. Removing lines from test-cli.sh, the issue starts occurring after the first cURL call to the swipe REST endpoint.

@twystd
Copy link
Collaborator

twystd commented Oct 14, 2022

Yup, it's an actual bug - somehow the JSON device file is getting serialized with an event list that looks like this:

  "events": {
    "size": 0,
    "chunk": 0,
    "index": 0,
    "events": [
      {
        "index": 1,
        "type": 2,
        "granted": true,
       ...

which triggers another bug in the deserialisation where it attempts to truncate the event list to the correct size:

...
	for len(l.events) > int(l.size) {
		l.events = l.events[l.chunk:]
	}
...

It can be reproduced with just one instance of the simulator and the test-cli.sh script.

@uhppoted
Copy link
Owner

The EventList wasn't being initialised correctly when unmarshalling a JSON file - I've pushed a partial fix to the master branch which does do the initialisation.

Hopefully that should sort out your immediate problem - I still need to take a look at the logic behind the infinite loop (it's been a while) and in general make this more robust.

@amprim
Copy link
Author

amprim commented Oct 15, 2022

Yup, that fixed it. The simulator now fully loads when a previous device file is loaded.

twystd pushed a commit that referenced this issue Oct 15, 2022
Reworked EventsList unmarshalling from JSON
- Added check for zero chunk size in EventsList::UnmarshalJSON
- Replaced zero values for EventList size and chunk with defaults
- Reworked truncation to use calculated offset rather than loop
@uhppoted
Copy link
Owner

Ok, root cause was that the events list was not initialised in the simulator default constructor, which is how it ended up with:

"events": {
    "size": 0,
    "chunk": 0,
...

Have fixed that and also:

  • used reasonable defaults if for some reason the size or the chunk is zero
  • reworked trimming the events list to use truncation rather than a loop

Think that fixes this in a way that I'm happy with - will leave this open for another day or two in case anything related crops up.

@uhppoted
Copy link
Owner

Closing this as fixed - feel free to reopen if you need to :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Status: Done
Development

No branches or pull requests

3 participants