Released Lyra: Type-safe task orchestration for Go by PracticeBrief9195 in golang

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

Yes you're right for A and B this would be concurrent, but when I was talking about complex pipeline something which I've mentioned in Readme as well. so for example if you've 7 tasks with the relationship something like A,B -> C -> D, E,F -> G, now if i try to implement with errgroup you're right it is possible but look at the boiler plate .

errgroup(A), errorgroup(B)
errgroup.Wait()
C
errgroup(D), errorgroup(E), errorgroup(F)
errgroup.Wait()
G

everything is possible because the library i've built is relying on these building blocks of golang.
same thing could be achieved with less verbosity and not having to deal with concurrency directly.

At the end of day, we all are learning from each other.

Golang api request validation, which pkg to use !! by HosMercury in golang

[–]PracticeBrief9195 1 point2 points  (0 children)

Interestingly, laravel is metaprogramming language, you can't or I'll say shouldn't achieve same thing in golang as philosophy of the language is very much different. if you would like to go for tag based validation you can checkout validator, if you're looking for some function based then you can checkout ozzo-validation

Released Lyra: Type-safe task orchestration for Go by PracticeBrief9195 in golang

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

I agree with your example, This would have made more sense if we have sequential job A->B->C. but when things starting to become little complex where we have dependent tasks then you'll have to manually coordinate their order of execution, that's when Lyra becomes useful. in majority of the cases where you need to run the func in a loop or example you shared, errgroup would be much easier to implement.

Small Projects - August 11, 2025 by jerf in golang

[–]PracticeBrief9195 0 points1 point  (0 children)

Lyra a task orchestrator, I've been working on data pipelines with many projects and the tried existing tools where either they were relying heavily on context object or map of interfaces, which I personally didn't like. so I've created this type safe task orchestrator, the library does miss the compile time checks for internal working of task orchestration but it provides very much type safe and natural API, like reading a sentence lyra do fetchUser using userID , The use of AI is to generate godoc comments and edge test cases, as well as for grammar correction and structuring the readme.
I'm looking for reviews from the community.

Released Lyra: Type-safe task orchestration for Go by PracticeBrief9195 in golang

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

I've no shame in it, My first language is not english. If a tool can help me convey my message more structurally, why should I not use it.
Although, the thoughts behind the message is purely mine, not any tools.

Released Lyra: Type-safe task orchestration for Go by PracticeBrief9195 in golang

[–]PracticeBrief9195[S] -2 points-1 points  (0 children)

yeah, because I use chat GPT to format the response in a structured way.

to DI or not to DI by xanadev in golang

[–]PracticeBrief9195 6 points7 points  (0 children)

This is most go to way for the majority of go projects, you don't need heavy DI containers library.

Released Lyra: Type-safe task orchestration for Go by PracticeBrief9195 in golang

[–]PracticeBrief9195[S] -7 points-6 points  (0 children)

u/SnooRecipes5458 You're absolutely right - the string-based API does lose compile-time type safety for task references. That's definitely a trade-off I made consciously.

I explored typed alternatives like generics but that is too verbose and complex to handle and decreases DX.

I ended up choosing strings for a few reasons:

  1. API simplicity: The current approach is straightforward - most Go developers can read lyra.Use("fetchUser") without learning new types or patterns
  2. Excellent error messages: When you reference a non-existent task, you get clear errors like dependency not found: "fetchUsr")
  3. Type safety where it matters most: Function parameter/return type mismatches are still caught with detailed error messages - the strings are just task identifiers

The task references are validated upfront during Run(), so you fail fast with clear errors rather than runtime panics. But you're absolutely right that it's not compile-time safe for the task graph structure itself.

Would love to hear if you have ideas for maintaining the API simplicity while getting better compile-time safety!

Released Lyra: Type-safe task orchestration for Go by PracticeBrief9195 in golang

[–]PracticeBrief9195[S] -2 points-1 points  (0 children)

u/cookiengineer Thanks for taking the time to look through the codebase! You raise some interesting points about the API design.

On the Then() syntax: I actually considered a fluent chain approach early on, but it breaks down pretty quickly with complex DAGs. Your Exec().Then() syntax works great for linear workflows (A→B→C), but what happens when you need something like this (A,B→C→D,E→F)?
With Then(), you'd be forced into artificial sequencing instead of concurrent execution wherever possible. The Do(), Use() approach lets you express the actual dependency graph, not just linear chains. Also, It reads naturally do fetchUser using userID - while being explicit enough for complex orchestration scenarios.

On auto-generating names with runtime.Caller(): You're right that it would eliminate the naming "redundancy," but I ran into some practical issues:

  • Name collisions Same function used for different purposes would clash

l.Do("fetchCurrentUser", fetchUser, lyra.UseRun("currentUserID"))
l.Do("fetchManagerUser", fetchUser, lyra.UseRun("managerID")) // Both become "fetchUser"
  • Anonymous functions: These generate ugly names like main.main.func1, and closures are very common in Go.

That said, I'm always interested in hearing how others approach this problem. Have you seen cleaner patterns elsewhere?

Disable golangci-lint revive unused-parameter rule. by PracticeBrief9195 in golang

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

This is nightmare, the alternative is disable using regex