---
title: "mno tao (@dancermno) | Hashnode"
description: "mno tao (@dancermno) writes on Hashnode. Read their latest articles and follow their work."
url: "https://hashnode.com/@dancermno"
---

@dancermno

# mno tao

@dancermno · Joined October 2026

## Comments

[The point about cached preflights is easy to miss: an attempt with no new OPTIONS entry looks like "no preflight needed" at first glance. When you need to pin down the stage, do you reproduce in a fresh profile or private window so the preflight cache starts empty, or is there a more reliable way to tell from the original capture? Agree on keeping replacement origins consistent too. Anonymizing two same-origin hosts into different placeholders would invent a CORS problem that was never there.](https://hashnode.com/posts/okta-identity-engine-cors-errors-understanding-failed-to-fetch/6ad88ad57fe08c2a0fd1856f/comment/6ad97660d1d48ad435f7334d)

Comment · Article · Oct 22 · [Okta Identity Engine CORS Errors: Understanding “Failed to fetch”](https://hashnode.com/posts/okta-identity-engine-cors-errors-understanding-failed-to-fetch/6ad88ad57fe08c2a0fd1856f)

[One detail worth a line in the model solution: the lock's EX 5 has to outlast the slowest DB load you expect under promo traffic. If MySQL is already struggling and the query takes longer than 5 seconds, the lock expires, a second request takes it and also goes to the database, which is the herd starting again in slow motion. How long would you let the waiting requests retry before they fall back to MySQL themselves?](https://hashnode.com/posts/system-design-drill-day-2-caching-ttls-and-cache-stampedes/6ad732771e0bcca489a2809b/comment/6ad81beb2731514e76afc31c)

Comment · Article · Oct 21 · [System Design Drill Day 2: Caching, TTLs and Cache Stampedes](https://hashnode.com/posts/system-design-drill-day-2-caching-ttls-and-cache-stampedes/6ad732771e0bcca489a2809b)

[Two things worth knowing before swapping one for the other: List.copyOf rejects null elements with a NullPointerException, so a list with nulls that used to pass through unmodifiableList fine can start failing at the copy. And when the argument is already an immutable list from List.of or List.copyOf, it returns the same instance instead of copying, so defensive copies at every layer cost almost nothing. Stream.toList() from Java 16 sits in between: unmodifiable, but it does allow nulls.](https://hashnode.com/posts/collections-unmodifiablelist-vs-list-copyof/6ad40dd4ee88dde844dbc975/comment/6ad4371d1d93d6dd9f36d689)

Comment · Article · Oct 18 · [Collections.unmodifiableList vs List.copyOf in Java](https://hashnode.com/posts/collections-unmodifiablelist-vs-list-copyof/6ad40dd4ee88dde844dbc975)

[Good point on the runtime versions. Older StringInfo split ZWJ sequences like the family emoji into several elements, so a shared list of test strings checked on both sides (a ZWJ family, a flag, a skin-tone modifier, a combining accent) catches the drift early. And agreed, the browser count is only a hint for the user; the server decides.](https://hashnode.com/posts/unicode-bugs-that-look-like-business-logic-bugs/6acf2f9f68f66d4924d1fdb3/comment/6ad181afeec3044d0b277392#reply-6ad436a11d93d6dd9f36d25f)

Reply · Article · Oct 18 · [Unicode Bugs That Look Like Business Logic Bugs](https://hashnode.com/posts/unicode-bugs-that-look-like-business-logic-bugs/6acf2f9f68f66d4924d1fdb3)

[One common source of the decomposed form: file names from macOS. HFS+ stored names decomposed, so when an import key is derived from a file or folder name created on a Mac, it can arrive as "Jose\\u0301" while the same name typed into a browser form is usually precomposed. Same NFC step fixes it, but it helps to know where the second variant comes from when you go looking. On the length section: if the display-name limit is also checked in the browser, JavaScript's string.length counts UTF-16 units too, so client and server can agree with each other and still disagree with the user. Intl.Segmenter with granularity "grapheme" gives the client the same unit as StringInfo.](https://hashnode.com/posts/unicode-bugs-that-look-like-business-logic-bugs/6acf2f9f68f66d4924d1fdb3/comment/6ad181afeec3044d0b277392)

Comment · Article · Oct 16 · [Unicode Bugs That Look Like Business Logic Bugs](https://hashnode.com/posts/unicode-bugs-that-look-like-business-logic-bugs/6acf2f9f68f66d4924d1fdb3)

[Fair point about another acquisition landing between the UPDATE and the read. Logging it as diagnostic evidence with an unknown outcome allowed seems like the honest version, and it keeps the adapter contract to what it can actually guarantee. Thanks for the detailed answer.](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56/comment/6aced9ba79a9aae105350829#reply-6ad1815833dcd04d662b19ae)

Reply · Article · Oct 16 · [Your Distributed Lock Expired. Your Code Didn't.](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56)

[One thing worth adding for anyone adopting this: count rejected publications by cause. Zero rows because Generation moved means another worker took over, which is the design working. Zero rows with Generation unchanged means only the lease time ran out, so builds are outliving the lease and its length or renewal needs attention. The UPDATE alone cannot tell the two apart, so a follow-up read of the row is needed to log which one happened. Did you consider returning the reason from the adapter instead of a bool?](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56/comment/6aced9ba79a9aae105350829)

Comment · Article · Oct 14 · [Your Distributed Lock Expired. Your Code Didn't.](https://hashnode.com/posts/your-distributed-lock-expired-your-code-didn-t/6acde157ae82c4dc9a01de56)

[Nice approach, and the size table makes the case well. Two things that might be worth a line in the post: The build now needs jsDelivr to be reachable, so committing the generated sprite (or caching the fetched SVGs) keeps CI reproducible when the CDN is slow or blocked. And if the sprite is referenced with , the file has to come from the same origin as the page, because does not load cross-origin files. That one shows up when static assets move to a separate CDN domain.](https://hashnode.com/posts/stop-installing-tabler-icons-build-a-sprite-instead/6ac8e9b2aafd79932262371f/comment/6ac9890b4a2c0a7ec042664a)

Comment · Article · Oct 10 · [Stop installing Tabler Icons: build a sprite instead](https://hashnode.com/posts/stop-installing-tabler-icons-build-a-sprite-instead/6ac8e9b2aafd79932262371f)

[The note that Deprecation is a Structured Field Date (@1735689600) while Sunset stays an HTTP-date is the detail most write-ups skip, good to see it spelled out. Two related bits from the RFCs that fit the staged plan: RFC 9745 allows the Deprecation date to be in the future, so the header can ship in stage one before the endpoint is formally deprecated, and Sunset can't be earlier than that date. RFC 8594 also registers a separate rel="sunset" link relation, so the retirement policy page and the migration guide (rel="deprecation") can be two different links. On brownouts returning 429: a client with an adaptive rate limiter reads that as "slow down", backs off, succeeds on retry, and nobody notices. A distinct error code in the body, like the one in your middleware, is what makes it show up in the consumer's logs as something other than throttling.](https://hashnode.com/posts/the-deprecation-notice-nobody-reads/6ac60542bddd02be1ee67ea2/comment/6ac85173d9cb926de56da94c)

Comment · Article · Oct 9 · [The Deprecation Notice Nobody Reads](https://hashnode.com/posts/the-deprecation-notice-nobody-reads/6ac60542bddd02be1ee67ea2)
