paulasmuth/fnordmetric — Issue #14: Race condition in submittion events
Author: arctica
Created: 2011-12-30 10:22:06+00:00
State: open

The example code from the Readme for submitting events has a race condition.

```ruby
redis.lpush("fnordmetric-queue", uuid)
redis.set("fnordmetric-event-#{my_uuid}", event)
redis.expire("fnordmetric-event-#{my_uuid}", 60)
```

I assume the receiving side does a (blocking) lPop. Following order of events can happen:

1. Client does lPush on the queue
2. Server does blPop on the queue
3. Server does Get on the key (fails, not found)
3. Client does Set on the key
4. Client does Expire on the key

To prevent the race condition the code needs to be re-ordered to

```ruby
redis.set("fnordmetric-event-#{my_uuid}", event)
redis.expire("fnordmetric-event-#{my_uuid}", 60)
redis.lpush("fnordmetric-queue", uuid)
```

to guarantee that any Get on the key that was Pop'd from the queue will succeed unless the key already expired.
Alternatively one could pipe the commands on the client so they are executed in one atomic step in Redis which will also save roundtrip times.
Additionally you can combine the Set and Expire into a single SETEX call.