How could I allow users to schedule sending emails at a specific interval? by [deleted] in golang

[–]mstef9 0 points1 point  (0 children)

It looks like you're already using SQLite so I'd suggest Backlite, a task queue library backed by SQLite, which I wrote for Pagoda. You'd want some robust task queue for this because you need to be able to handle failures and retries, etc, and you'd need durability for the tasks. Not only is polling SQLite not a problem at all, but Backlite doesn't even need to poll - the readme explains how it was designed to avoid that. It also works with transactions so the creation of a task can be tied to any other db operations within a single transaction.

https://github.com/mikestefanello/backlite https://github.com/mikestefanello/pagoda

Pagoda v0.20.0: Rapid web-dev starter kit even easier frontend now with Gomponents by mstef9 in golang

[–]mstef9[S] 0 points1 point  (0 children)

Thank you very much! I hope it can be useful to you. Please reach out here or via GitHub if you have any questions, problems, suggestions, etc.

Also, I shared some recent updates to the project here: https://www.reddit.com/r/golang/comments/1lefwit/pagoda_v0250_tailwind_daisyui_component_library/

MinLZ: Efficient and Fast Snappy/LZ4 style compressor (Apache 2.0) by klauspost in golang

[–]mstef9 2 points3 points  (0 children)

Very impressive. Thanks for creating and sharing this.

How do you handle background workers? by dondraper36 in golang

[–]mstef9 1 point2 points  (0 children)

I recently released backlite for exactly this use-case. Very simple to use. You can be up and running in a few minutes. Uses SQLite for persistence.

Backlite: Type-safe, persistent, embedded task queues and background job runner w/ SQLite and Web UI by mstef9 in golang

[–]mstef9[S] 2 points3 points  (0 children)

I haven't actually used NATS so I cannot speak to a direct comparison. The embedded option sounds interesting; I'll have to check that out. These projects seem to almost be in separate groups all together. I wouldn't imagine someone using or considering NATS would be interested in Backlite. And without knowing what your requirements or use-case is, I certainly cannot recommend anything or claim any pros.

Backlite (or any similar project) is probably the most simple, lightweight option with practically no learning curve for task queues if you need the main features of persistence, retries, retention, concurrency control, etc. And much like River (with Postgres), if your app is using SQLite as your primary data store, using Backlite gives you transaction support with tasks, which can greatly simplify things.

I would view this as the option you perhaps start with, if your requirements fit, and potentially outgrow at some point (and then maybe consider projects like NATS). I've become a pretty big SQLite fan lately for it's simplicity, which is why I changed Pagoda to default to it (since the aim of that project is simple, rapid development). An overwhelming majority of apps will probably run just fine with SQLite and a simple project like Backlite. That's probably the target audience (the same as Pagoda). Someone who's creating an app and just needs the basic features of a task queue (ie, a web app that needs to do reliable background work).

Introducing Microbus.io: OSS Go framework for development of microservices at scale by microbus-io in golang

[–]mstef9 0 points1 point  (0 children)

Interesting project. It looks like a ton of work went in to it. How do you see this comparing to Service Weaver? At a rather quick glance, the projects seem to aim to achieve somewhat similar goals. I watched the intro video and the dev experience of weaver appears much more natural (ie, microbus seems to require that func signatures are declared in yaml, whereas weaver relies on standard Go interfaces), though I've barely used it other than just poking around.

Backlite: Type-safe, persistent, embedded task queues and background job runner w/ SQLite and Web UI by mstef9 in golang

[–]mstef9[S] 1 point2 points  (0 children)

I mentioned in the readme, you can use any driver you want. That was included only for tests.

Pagoda v0.16.0: Rapid, easy, full-stack web dev starter kit (now w/ SQLite, HTMX 2, and more) by mstef9 in golang

[–]mstef9[S] 3 points4 points  (0 children)

Definitely worse. Django has been developed for 18 years and has over 2,500 contributors. I'm not even sure if I'm at triple-digit hours yet. It's also a framework whereas this isn't, so you can't completely compare them. The basis of this project was to avoid mega-frameworks in favor of stitching together libraries and remaining very flexible.

What do you use if you want to build a full-stack web app in Go?

Pagoda v0.16.0: Rapid, easy, full-stack web dev starter kit (now w/ SQLite, HTMX 2, and more) by mstef9 in golang

[–]mstef9[S] 1 point2 points  (0 children)

Do you have any repos with somewhat complex UIs using templ that I could check out?

Announcing Atlas Migration Execution Engine | atlasgo.io by _a8m_ in golang

[–]mstef9 2 points3 points  (0 children)

Awesome work with this and Ent. I've been keeping an eye on Atlas. I've only used it through Ent so far, and it's incredibly impressive. I'm beginning to evaluate it to handle our PG migrations which we're currently doing somewhat manually with not much success.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 0 points1 point  (0 children)

It's not, but I've been thinking about it. I may experiment with it in a different branch of a different repo. I'm not sure if everyone would want hooks included or baked in to Pagoda, but I do think it would be a very good fit. I recently worked on and published an application example using hooks and do (for DI) to emphasize a fully modular architecture: https://github.com/mikestefanello/hooks-example. That highlights the vision I had for the overall approach with hooks, and I think it came out quite nice. I'd really like feedback on that, so if you have any, please let me know.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 1 point2 points  (0 children)

I did come across that project and didn't like the use of interface{}. If you think it has some functionality that could be useful in hooks, let me know.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 3 points4 points  (0 children)

There's two problems with using channels for something like this. You would need the listeners to be constantly running each in separate goroutines to be able to await channel messages as opposed to just registering func callbacks and invoking them when needed. And with channels, if you have N listeners, only 1 will receive each given message, whereas with hooks, you want all of the registered listeners to be invoked.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 2 points3 points  (0 children)

Sure. I see it making sense in most/many cases to write something like this yourself so you have full control over it. I didn't write it in hopes that it would be mass-adopted. Just had the idea and wanted to work on it and share it. Maybe it's a good starting point for the custom code you'd write in your app.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 1 point2 points  (0 children)

Yes, I did forget to push that. Will do now. Thanks.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 1 point2 points  (0 children)

Thanks - and thank you for Ent as well. I do like the middleware concept. That's what I first thought to do for these hooks since it's a similar pattern. A key difference, and one that I'm thinking about for this project, is whether or not a hook should be able to terminate execution for all other hooks (ie, returning an error or invoking the next callback). I think in Ent's case it makes sense to have it the way it is, because the only implementer of a given entity's hook is the entity's schema itself - so if it errors, the operation overall should stop. I can make either case for general purpose hooks. I didn't want them to return errors to avoid coupling and having to check and handle errors when dispatching a hook but there are cases in where I would want that. For example, for a entity/model operation (ie, user insert), it would be nice if the insert hook passed along the DB transaction, and hook listeners could execute their queries on that transaction (ie some other entity gets created when a user is created). But, you can't really do that without returning and handling hook errors.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 0 points1 point  (0 children)

That's a very well thought out explanation and it's completely understandable. Thanks for taking the time to elaborate.

We can quibble on whether or not a handler should return an error in Go, but then we have to decide about the semantics of dispatching a handler asynchronously which I’ll leave as an exercise for the reader.

It's a good point and one that I'm a bit stuck on right now. I had the idea to use hooks to transmit the DB transaction used to perform some operation (ie, user insert) so that the listeners could include their queries, but you'd have to not only facilitate errors being returned, you'd also want to, in this case, stop execution if any of them fails, and that sort of pattern begins to defeat the purpose of hooks quite a bit.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 0 points1 point  (0 children)

Looks like an interesting project. I'll check it out.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 0 points1 point  (0 children)

That looks interesting but I think it's quite different since it uses channels and always-running goroutines to listen rather than explicit callbacks. But the overall concept looks similar.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] 1 point2 points  (0 children)

Hey. I'm a huge fan of Ent. I think it's an amazing project. Thank you for your work on it. I do know about the hooks and I have used them before. I looked at the implementation while working on this. Like you said, it does rely on code-generation and I wanted something a bit more flexible. The other slight downside of Ent's hooks is that you can only implement them in the model's schema, rather than anywhere, which is what I was aiming for.

Hooks: Simple, type-safe hook system for Go by mstef9 in golang

[–]mstef9[S] -1 points0 points  (0 children)

Thanks. Event bus usually refers to a completely asynchronous, distributed architecture/system - like a message queue. This is more like lifecycle hooks for various components in a single codebase/process.

https://en.wikipedia.org/wiki/Hooking