5,413 karma · joined February 4, 2014
Edit: Here's the MDN bit on that, I was correct:
https://developer.mozilla.org/en-US/docs/Web/API/Window/setT...
> browsers will enforce a minimum timeout of 4 milliseconds once a nested call to setTimeout has been scheduled 5 times.
And the link from there to the spec about that:
https://html.spec.whatwg.org/multipage/timers-and-user-promp...
> If nesting level is greater than 5, and timeout is less than 4, then set timeout to 4.
Also, audio interfaces incur different amounts of mental load / distraction. I wouldn't be surprised if this was more distracting than just talking to a person.
IIUC, InstantDB is open source with a docker container you can run yourself, but at this point it's designed to run in a more cloud-like environment than I'd like. Last time I checked there was at least one open PR to make it easier to run in a different environment, but I haven't check in recently.
The PWA capabilities of webapps are pretty OK at this point. You can even drive notifications from the iOS pinned PWA apps, so personally, I get all I need from web apps pretending to be mobile apps.
I've been writing a budget app for my wife and I and I've made it 100% free with 3rd party hosting:
* InstantDB free tier allows 1 dev. That's the remote sync.
* Netlify for the static hosting
* Free private gitlab ci/cd for running some email notification polling, basically a poor mans hosted cron.
I think it boils down to provenance and concurrency. If we edit the same line a file, that's ba merge conflict when it really should be simple and something I shouldn't have to bother with. And when we do do the same line edit, I'd love to have provenance on that data.
Granted, those aren't local first thing exactly, but I think there will be apps that want all of that.
I should probably write a blog post, but I will say that I investigated power sync, electricSQL, livestore and powersync before. I briefly looked at jazz tools but wanted something a bit more structured.
I'm pretty impressed this far. I've actually been writing it with Vue and a community library. Permissions were a bit tricky, but once I figured it out it was simple. And I like their magic email login. And I like their dashboard/reply, but there are a few big changes I would make there to make it less fiddly.
I love that it's open source, and that if I want to, I could self host it.
As for the other options:
- jazz wasn't structured enough
- livestore came off as too fiddly with the event store, but it was appealing. That the dev tools are payealled was disappointing, but understandable
- electriSQL really only provided half a solution (read, not the write model
- couchDB / pouchDB wasn't structured enough for me, and I wanted better cross document support than was obvious / baked in.
- did not investigate zero really
First is that yeah, local first, but I also want concurrency. If it's just local first, you're right, any old sync will do. But I want more than that. I want to not have to think (a la dropbox, being slick). I want my wife and I to be able to make separate edits on our phones when we're in a dead zone.
Second is that sync works a lot better when it has deep knowledge of the data structure and semantics. Git and box both have significant shortcomings, but both exacerbated by the concurrency desire.
Basic goals:
- Web based for zero update latency
- Have it work offline
- Automatically import transactions from my banks
- No running/hosting cost
- Secure
Tools used so far:
- InstantDB for the datastore, providing the offline capability too
- A gmail account that automatically gets forwarded bank alerts for purchases
- Gitlab.com w/scehduled pipelines for cron based email-syncing
- Netlify for the free hosting
- InstantDB magic codes / email links for securing the data
I'm at the point where I can track and categorize purchases, including split transactions.
Next steps:
- Add in date ranges for reporting / data views; e.g. show expenses incurred in a one month period instead of for all time.
- Add in planned / project transactions for month forecasting
- Statement import & import reconciliation and statement reconciliation
- Scrape company specific digital reciept emails (like Amazon) to autopopulate more transaction data
And that'll be the end of the stuff I can do for free. I think I will add features that require money and/or dedicated hardware though:
- OCRing receipts -> autopopulated transaction data / description
- Using chatgpt to suggest categorizations
- Scrape extra data from my bank sites, like physical addresses of entities involved in charges.
~1:00 CT: AWS outage start, GCP outage start
~1:15 CT: NPM registry
~1:19 CT: Github & Cloudflar
"The hardest thing to internalize about virtual threads is that, while they have the same behavior as platform threads they should not represent the same program concept."
...
"Sometimes there is a need to limit the concurrency of a certain operation. For example, some external service may not be able to handle more than ten concurrent requests. Because platform threads are a precious resource that is usually managed in a pool, thread pools have become so ubiquitious that they're used for this purpose of restricting concurrency, "
...
"But restricting concurrency is only a side-effect of thread pools' operation. Pools are designed to share scarce resources, and virtual threads aren’t scarce and therefore should never be pooled!
"When using virtual threads, if you want to limit the concurrency of accessing some service, you should use a construct designed specifically for that purpose: the Semaphore class."
...
"Simply blocking some virtual threads with a semaphore may appear to be substantially different from submitting tasks to a fixed thread pool, but it isn't. Submitting tasks to a thread pool queues them up for later execution, but the semaphore internally (or any other blocking synchronization construct for that matter) creates a queue of threads that are blocked on it that mirrors the queue of tasks waiting for a pooled thread to execute them. Because virtual threads are tasks, the resulting structure is equivalent"
"Even though you can think of a pool of platform threads as workers processing tasks that they pull from a queue and of virtual threads as the tasks themselves, blocked until they may continue, the underlying representation in the computer is virtually identical. _Recognizing the equivalence between queued tasks and blocked threads will help you make the most of virtual threads._" (emphasis mine)
So it was cool seeing him arrive at the same conclusion (or he read the docss). Either way it was a nice timely article.
Link to the docs: https://docs.oracle.com/en/java/javase/21/core/virtual-threa...
Which I could see that being a deal breaker, but maybe it's lower than you thought