[{"data":1,"prerenderedAt":81},["ShallowReactive",2],{"api:\u002Fapi\u002Fconfig:en":3,"api:\u002Fapi\u002Fnotes:en":8,"api:\u002Fapi\u002Fprojects\u002Fuptime-monitor:en":32},{"email":4,"lang":5,"name":6,"role":7},"hello@ewsirdev.example","en","Ewsirdev","Web developer: websites, landing pages and Go services",[9,16,22,27],{"slug":10,"lang":5,"title":11,"date":12,"summary":13,"project":14,"minutes":15},"double-booking","Double booking: a transaction plus a partial UNIQUE index","2026-10-20","How booking-slots protects against two clients booking the same time at once, and how that protection is tested.","booking-slots",1,{"slug":17,"lang":5,"title":18,"date":12,"summary":19,"project":20,"minutes":21},"lease-and-fencing","Lease and fencing: how a queue neither loses a job nor lets a zombie finish it twice","A worker can crash, stall, or wake up after its job was taken by someone else. How the lease and the lease token in job-queue deal with that on SQLite.","job-queue",2,{"slug":23,"lang":5,"title":24,"date":12,"summary":25,"project":26,"minutes":21},"p95-nearest-rank","p95 in an uptime monitor: the nearest-rank method and what it does not hide","How uptime-monitor computes p50\u002Fp95 latency and uptime, why the nearest-rank method was chosen, and where those numbers can mislead.","uptime-monitor",{"slug":28,"lang":5,"title":29,"date":12,"summary":30,"project":31,"minutes":21},"websocket-from-scratch","WebSocket on the standard library: what really happens under new WebSocket()","Why realtime-rooms has its own RFC 6455 layer, which protocol violations it checks, and why a library is still the better choice for production.","realtime-rooms",{"slug":26,"title":33,"type":34,"stack":35,"description":41,"highlights":42,"run":47,"hue":48,"og":49,"shots":50,"case":58,"case_lang":5,"prev":76,"next":79},"Pulse: uptime monitor","backend",[36,37,38,39,40],"Go","SQLite","SSE","REST API","Docker","An uptime monitor: scheduled HTTP and TCP checks, uptime, p50\u002Fp95, an incident detector, a live SSE dashboard and a public status page. Go + SQLite without CGO.",[43,44,45,46],"A worker goroutine per check","Incidents after a series of failures","SSE dashboard and a public \u002Fstatus","Tests and Docker","cd uptime-monitor && set SEED_DEMO=1&& go run .\u002Fcmd\u002Fserver",101,"\u002Fog\u002Fen\u002Fuptime-monitor.jpg",{"desktop":51,"desktop_sm":52,"mobile":53,"dw":54,"dh":55,"mw":56,"mh":57},"\u002Fshots\u002Fuptime-monitor-desktop.webp","\u002Fshots\u002Fuptime-monitor-desktop-sm.webp","\u002Fshots\u002Fuptime-monitor-mobile.webp",1280,800,390,844,{"about":59,"features":62,"run":69,"notes":73},[60,61],"Pulse is an uptime monitor: it checks HTTP addresses and TCP ports on a schedule, keeps the history in SQLite, calculates uptime and p50\u002Fp95 latency, and opens an incident after a series of consecutive failures.","Results appear on a live dashboard (updates over SSE) and on a public status page that does not reveal addresses or error texts. Go with no external dependencies except SQLite without CGO; the vanilla JS front end is embedded in the binary.",[63,64,65,66,67,68],"One worker goroutine per check with its own interval and timeout; runs for the same address never overlap","HTTP GET (expected status, up to 5 redirects) and TCP connect","Uptime over 24 h, 7 and 30 days, and p50\u002Fp95 latency over 24 h","Incident detector: opens after N failures in a row, closes on the first success, survives a restart","REST API behind a Bearer token, an SSE event stream, graceful shutdown, slog logging","Tests (scheduler, detector, statistics, API, SSE) and Docker",[70,71,72],"git clone \u003Crepository on request> uptime-monitor","cd uptime-monitor","SEED_DEMO=1 go run .\u002Fcmd\u002Fserver   # http:\u002F\u002Flocalhost:8084, token demo",[74,75],"In demo mode the history is generated to make the charts readable; everything that appears after startup is measured for real.","One node and one token, no notifications, and checks run only from the service's own machine. Uptime is calculated from the number of checks, and the HTTP response body is not analysed.",{"slug":77,"title":78},"landing-event","Small Scale: conference",{"slug":20,"title":80},"Conveyor: job queue",1792697892725]