Premier League Predictor: FastAPI & Redis — Chapter 5, Exercise 2 ================================================================= TASK Extend the Lua script so it refuses to write when the fixture itself does not exist, returning -1 for that case (0 stays "locked", 1 stays "written"). Run it against a nonexistent fixture, an open fixture, and a locked fixture, and report all three results. SOLUTION PREDICT_LUA = """ if redis.call('EXISTS', KEYS[1]) == 0 then return -1 end -- no such fixture local hs = redis.call('HGET', KEYS[1], 'home_score') if hs and hs ~= '' then return 0 end -- locked redis.call('HSET', KEYS[2], ARGV[1], ARGV[2]) return 1 -- written """ predict = r.register_script(PREDICT_LUA) Real results: nonexistent fixture:777 -> -1 (fixture:777:predictions exists? 0) open fixture:1 -> 1 (user stored: '2-1') locked fixture:1 (result 2-1 entered) -> 0 (user still '2-1', not '9-9') Each of the three outcomes is distinct, and the nonexistent case leaves no orphan hash behind: EXISTS on the predictions key afterwards returns 0. The route can map the three return values to HTTP responses: -1 -> 404, 0 -> 409 (locked), 1 -> 200/201. WHY THIS WORKS AS AN ANSWER ---------------------------- The existence check sits inside the same script as the lock check and the write, so all three are atomic together. Doing EXISTS as a separate call before the script would reopen a (small) gap between them; putting it in the script is what makes it a real guard rather than a courtesy check.