1. Services like this cron with Dyno Deploy or Vercel where the cloud things are abstracted away for you.
2. I have no data to back it up but it seems like JVM is experience a bit of a comeback with a few companies adopting Kotlin for backend and, also subjectively, talk about Elixir has increased here on Hacker News (we've all seen that table that shows how the Erlang VM is cron/background jobs/logging service/KV store all rolled into one). And if those are not the trends I feel like they should be.
Both of those are very appealing to me as a team lead. Honestly, I have never been a fan of managing services in AWS/GCP/etc - the setup overhead rarely seemed to outweigh the pros, at least until some heavy amount of data start moving around. I might be stating the obvious - less work is definitely better, but pretty much every company I have consulted for in the last few years had a (crappy) bespoke cloud setup that was a massive time sink.
We need more well rounded people that also fundamentally understand how their code is executing on the backend so performance and cost can be optimized.
> it seems like JVM is experience a bit of a comeback with a few companies adopting Kotlin for backend
JVM 21 adding virtual threads, and Spring Boot 3.2 using them with one line of config is huge. We can now write simple code that looks blocking and let the runtime handle it instead of writing async function/await everywhere. Personally I'm loving Spring Boot 3.2 with Kotlin, especially for the fact that I can bundle scheduled jobs, API, and frontend all in one place for my indie projects. Plus the JVM world of devs seems to have a somewhat decent appreciation of how to make web services that aren't rife with unnecessary coupling.
The bad? There is a legendary amount of cargo-culting blog posts and questionable advice around Spring Boot, often for older versions.
> We have no dedicated devops person
I understand that not every startup can afford an extra person for infra-heavy tasks, but this should not be surprising. Any tool which looks like an abstraction to you might get complex by time, and steal your time. The cloud was supposed to fix some of these, look where we are now.
Unlike other people I don't think you need to hire someone directly. I do devops freelancing so you could hire someone like me. Or look online for various people that do it. I mean if its a toy app without many customers then who cares, but once you start scaling infrastructure gets to me more and more important.
Part of that shift is that prior to the cloud, the development environment and production environments were very similar. By that I mean if a programmer could set up his debian / redhat laptop from the command line, then it wasn't a big jump to set up a server running debian / redhat in a production environment.
But no one in their right mind runs k8s on their laptop just to support VSCode and a compiler. Worse they could not run AWS/GCP because they are proprietary, insanely large, complex and forever changing. I'm pretty sure becoming an expert engineer in those environments is a full time job. The end result is a new class of engineers have arisen that look after the production side, and the developers just throw their code over the wall once it's tested.
I'm sure the cloud providers love this, as they have created a cohort of engineers that have invested years in learning their product, now have their wages dependent on that product being used within their organisation, and a total monopoly over that product because it can never be reproduced by anyone else. But for the industry as a whole, it looks to be a backward step. Once the problem expands beyond what a single human mind can cope with, you need teams. The communication overhead of a team means they don't have a hope of being as productive as a single person.
The share amount of complexity introduced by these proprietary cloud frameworks looks to be unnecessary. Most of it smells like technical debit created by organic growth together with an insistence on backward compatibility (don't want to give those locked in customers an excuse to move). And desktop OS's are (Debian / Windows / ...) are insecure by design, at least when compared to their phone brethren. And, their phone brethren look somewhat like cloud designs now, Phones have isolated apps with private data areas. The apps communicate via channels provided by the OS, and the availability of those channels is controlled by permissions assigned by the user. In the cloud we isolated things for performance as they could run on distance machines, whereas in a personal device we did it for security. But the end result looks similar.
So maybe one day we will end up where we started, with a developer environment looking like the cloud we deploy too. I fear I'm too old to experience if / when it does happen, but it does seem like something we should aspire to.
- [0] Quantum, quite simple and supports cron syntax.
- [1] Oban, which is a job runner, requires a DB, but also supports periodic jobs with a cron syntax.
(probably others but that's the ones I've used)
I agree with the sentiment, but to me it’s a shame this even qualifies as abstraction in the first place. Periodic execution of a function is extremely basic and already exists in almost every programming environment. If this needs to be a service (instead of a library call), there is something deeply wrong elsewhere, imo. We all laughed about leftpad, but at least that was native code and not “as-a-service”, dependent on networking and proprietary code on someone else’s machine.
I have nothing against Deno in particular, and I’m also not saying this is easy from an implementation perspective (due to complexity elsewhere). I’m just surprised that trivial features – from an end-user perspective – justify such a ruckus.
Its well known how to deploy. Its easy to deploy. The footguns are vigorously and thoroughly documented. The frameworks (Symfony, Laravel) are good. They all have a solution for X (be it queues, async work, cron jobs etc) and they have turn key deploy solutions favored by their respective communities.
Its honestly one of the easiest languages to deploy with nowadays, in my estimation. Rivaled only by C# / F# or platforms like Deno Deploy or Cloudflare workers. Sometimes the most boring / mature thing is the best thing.
Sounds like you’d like to use a PaaS provider.
Heroku/Render/Fly/etc.
I just `ssh` into prod and `git pull` and either `docker compose up` or `kubectl apply` or `terraform apply` or `helm update` or `argocd sync`
I know that displaying artwork is not the point of the article, but please, at least make it believable when you look at it for more than one second.
Namely, I ran this example.
let s = 0, r = 0;
Deno.cron("Add second", "* * * * *", async () => {
console.log(`Add second ${s++}`);
});
Deno.serve(async (_req) => {
return new Response(`Seconds Running: ${s} / Number of requests: ${r++}`);
})
Example deployed here: https://weak-stoat-26.deno.devSo, effectively, it seems that Deno.Cron clones the JS context but any changes done to that context will not be reflected in the Deno.serve. And, if that's the case, why don't handle Cron jobs in a different flow rather than mixing them with Deno.serve? (I think it can lead to unintended side-effects)
I'd love if someone from the Deno team could provide more context here, maybe I missed something?
The blog post touts this as a feature to reduce the amount of code to get up and running, but a library would accomplish the same thing. A first-party library could even directly integrate with Deno Deploy in the same way that this appears to.
Why pollute the runtime with something unrelated?
But why not include any kind of schedule specifier that is a bit less cryptic and error prone? Is it really so much code?
Maybe someone has a package already that can wrap this or output a schedule from a human readable description or something. Maybe something like `human-to-cron`.
> When a new production deployment of your project is created, an ephemeral V8 isolate is used to evaluate your project’s top-level scope and to discover any Deno.cron definitions. A global cron scheduler is then updated with your project’s latest cron definitions, which includes updates to your existing crons, new crons, and deleted crons.
Having cron jobs defined in the code itself just feels weird. I get the convenience of doing things "in one place", but it's such an orthogonal concept. But I suppose combining things is part of the allure of deno any way.
Now that aside, the Flavor Flav dinosaur is the best thing I've seen all week.
This isn't quite that but close.
From my experience there 5 main components for larger scale system.
- Request server
- database
- queue
- background worker
- offline batch jobs
I feel like so far serverless has the first 3 fairly well developed but the last two are still underdeveloped.
But maybe I'm just not aware of other solutions?
I can see from comments like vvpan's that there is a fatigue around managing services in AWS/GCP/etc, but I have gone very much in the other direction in the last few years towards bare metal servers managed with NixOS. I feel much more confident in handling scheduled jobs on bare metal with Systemd timers than tying myself even deeper into a specific language+deployment solution ecosystem.
Timezones would be nice, "This helps avoid issues with time zones which observe daylight saving time." But it also causes issues with daylight saving time. I can't run something at 9 in the morning, I need to run it 1-2 hours before-hand, calculate the offset, and then queue a run 1-2 hours later. Or I can run 2 crons and have one or the other die early. Point being, all solutions become very hacky very fast.
It would be nice if an object was passed to the handler that had a targetDate for the ideal start time would be, so runs can be easily labeled and separated.
Yes I could round the Date.now() to the last minute, however, if Deploy ever goes over the minute boundary, that's all kaput.
In a similar vein: Systemd timers have some nice features, AccuracySec/RandomizedDelaySec/FixedRandomDelay, some options similar to that would be nice (of course, with minute resolution instead) (and of course, fixed delay can be pre-calculated, but it would be nice to just say 30m and have deno runtime manage that for me)
https://www.freedesktop.org/software/systemd/man/latest/syst...
Would be really awesome if this could be used to offload long lived jobs from the request.
Defer.run is building this for vercel and it’s really cool.
I spent a day or two migrating a TypeScript project [-1] over to Deno from NodeJS. Here's what I had to do:
* Change all of my local imports to something that would work with Deno. That meant appending `.ts` or `index.ts` for folders, except in some cases where Deno requires `.js`
* Modify my monorepo to play nice with Deno -- an import map does this easily. Deno has documentation around import maps, but I had to figure out the solution myself. Also, import maps are currently broken in JetBrains IDEs.
* Change my NPM imports to something that would work with Deno. The most straightforward thing to do was just change `import "foo"` to `import "npm:foo"`, but this felt hacky so eventually I used https://esm.sh, which worked for some packages but not others.
* Figure out how to get Lodash working with TypeScript. It's not simple. [0]
* Use a hack to get typeorm with sqlite working. [1]
* Try out `deno compile`, only to determine that it somehow works differently than `deno run`. My project simply wouldn't work with `deno compile`, probably because my project has some system dependencies that don't get properly linked/included.
* Setup my scripts to properly lint my project. Deno has formatting/linting built-in, but it's split across many commands with different usages. For example, I can run `deno fmt` to format my entire project, but I have to give Deno a path to run `check` or `lint`, e.g. `deno check src/index.ts `
* Patch a third-party library that was setting an HTTP header to `null`. NodeJS handles this case just fine, but Deno throws an error [2].
* Attempt to build my UI (astro + react) with Deno. It seems some people have gotten this partially working, but I gave up and stayed on NodeJS for building my UI. This led to me:
* Using dnt [3] to build a Deno package for consumption with NodeJS/npm frontend. This was actually surprisingly simple; kudos to the author of the dnt library.
After all of that work, I finally was able to use Deno in my project. It was really cool! Unfortunately, both VS Code and IntelliJ with Deno are essentially unusable [4]. Or, at least, unacceptably slow compared to what I had with NodeJS.
[-1]: https://github.com/shepherdjerred/glitter-boys/tree/sj/deno
[0]: https://stackoverflow.com/a/66073607
[1]: https://github.com/typeorm/typeorm/issues/6123#issuecomment-...
[2]: https://github.com/Sansossio/twisted/issues/97
Node/Deno/Bun/etc. + npm sounds super straightforward (and it is at first). But I've thought for years that it's far easier to be productive on the backend on .NET in Visual Studio, since it's simpler to design, deliver, and maintain infrastructure.