I’m stuck on Stage Blocking retrieval #EC3.
I have implemented BLPOP command with proxies and promises. but I keep getting an error that client 1 ( first subscriber of blpop ) received a different response. Maybe I didn’t understand the behavior of this command well enough. Please ignore the context from “your program” logs below if its confusing.
Here are my logs:
[compile] Moved ./.codecrafters/run.sh → ./your_program.sh
[compile] Compilation successful.
[tester::#EC3] Running tests for Stage #EC3 (Lists - Blocking retrieval)
[tester::#EC3] $ ./your_program.sh
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.267Z","context":{},"msg":"Logs from your program will appear here!"}
[tester::#EC3] [client-1] $ redis-cli BLPOP blueberry 0
[tester::#EC3] [client-2] $ redis-cli BLPOP blueberry 0
[tester::#EC3] [client-3] $ redis-cli RPUSH blueberry raspberry
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.324Z","context":{"traceId":"9f149790-2ad4-4517-a1bd-1f62bd7ccf02"},"msg":"BLPOP"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.324Z","context":{"traceId":"afc85221-5dff-476f-8127-dbcb7a65ffd5"},"msg":"BLPOP"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"RPUSH"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"Time Taken for execution - 1"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"calling mutation observers - 2"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"triggering callback"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"b94e6091-adf1-4e26-9854-fe6229483cf3"},"msg":"triggering callback"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"9f149790-2ad4-4517-a1bd-1f62bd7ccf02"},"msg":"result - blueberry,raspberry"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"afc85221-5dff-476f-8127-dbcb7a65ffd5"},"msg":"result - blueberry,raspberry"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"9f149790-2ad4-4517-a1bd-1f62bd7ccf02"},"msg":"Time Taken for execution - 1"}
[your_program] {"level":"INFO","time":"2026-04-29T08:14:37.325Z","context":{"traceId":"afc85221-5dff-476f-8127-dbcb7a65ffd5"},"msg":"Time Taken for execution - 1"}
[tester::#EC3] [client-3] ✔︎ Received 1
[tester::#EC3] Expecting 1 client to receive response of BLPOP command
[tester::#EC3] [client-2] ✔︎ Received ["blueberry", "raspberry"]
[tester::#EC3] [client-1] Expecting no response
[tester::#EC3] client-1 received unexpected response: "*2\r\n$9\r\nblueberry\r\n$9\r\nraspberry\r\n"
[tester::#EC3] Test failed
And here’s a snippet of my code:
const { logger } = require("../contextualLogger");
const { redisLookup } = require("../inMemoryLookup/index");
const {
encodeToRespBulkString,
encodeToRespArray,
} = require("../respParser/index");
const observersLookup = new Map();
function createObservableArray() {
let timeout;
let isManualMutation = false;
const observed = new Proxy([], {
set(target, prop, value) {
target[prop] = value;
if (!isManualMutation && observersLookup.get(observed)) {
// Clear and reset a timer so the logic runs only ONCE after the last set
clearTimeout(timeout);
timeout = setTimeout(() => {
isManualMutation = true;
const removedValue = observed.shift();
const callbacks = observersLookup.get(observed);
logger.info(`calling mutation observers - ${callbacks.length}`);
callbacks.forEach((cb) => cb(removedValue));
observersLookup.delete(observed);
isManualMutation = false;
}, 0);
}
return true;
},
});
return observed;
}
async function blPopCommand(listName, timer = 0) {
timer = +timer;
let list = redisLookup[listName];
if (!list) {
list = createObservableArray();
redisLookup[listName] = list;
}
let result;
if (!list[0]) {
let observersList = observersLookup.get(list);
if (!observersList) {
observersList = [];
observersLookup.set(list, observersList);
}
result = await new Promise((res, rej) => {
const callback = (removedValue) => {
logger.info("triggering callback");
res([listName, removedValue]);
};
observersList.push(callback);
if (timer) {
logger.info(`setting timer - ${timer}`);
setTimeout(() => {
observersLookup.set(
list,
observersList.filter((cb) => cb !== callback),
);
res([]);
}, timer * 1000);
}
});
logger.info(`result - ${result}`);
} else {
const removedValue = list.shift();
result = [listName, removedValue];
}
const res = encodeToRespArray(result.map(encodeToRespBulkString));
return res;
}
module.exports = {
blPopCommand,
};
I am attaching my github repo link with main.js files as well
CC Redis - main.js