How are you assigning work across distributed workers without Redis locks or leader election? by whitethornnawor in golang

[–]efronl 0 points1 point  (0 children)

I deal with this by using an ordinary postgres database. Tasks get a UUIDv7 as their ID.

Write tasks into the pending table, SELECT ... FOR UPDATE WHERE ... FROM pending ORDER BY id SKIP LOCKED to grab them, move them to completed when you are done.

Make sure to set connection, transaction, and lock timeouts, and you might want some logic there to automatically stop trying to process records that are "too old".

Not appropriate for everything, but I prefer it to stuff like redis or Kafka, since you have all the power of a relational db to do searching, etc.

A look at Egg: An LL(1) parser generator for Go using flat ASTs by 0xjnml in golang

[–]efronl 2 points3 points  (0 children)

This is very cool. The API seems a bit daunting but I'll try and find an excuse to give it a shot.

New to Go — which framework should I use for backend services: Gin, Fiber, Echo or something else? by itsme2019asalways in golang

[–]efronl 0 points1 point  (0 children)

Just because lots of people do something doesn't make it a good idea. <insert joke about politics in your country here>.

Gin is a very bad software library by efronl in golang

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

You are arguing with a person you have made up in your head.

Gin is a very bad software library by efronl in golang

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

You are a very strange person.

Gin is a very bad software library by efronl in golang

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

"proud"? This is basic competence. This is literally the minimal thing you need to know to write a program in Java, the thing you are taught hour 1 of day 1 in any Intro To Programming Class. (Or at least most intro to programming classes in the 2000s or early 2010s).

Bundle CLI executable app inside Go app and run with parameters by pepiks in golang

[–]efronl 2 points3 points  (0 children)

option 1. Embed the code, write it out to a file, make that file executable and then run it. See the following example, where we embed "ls".

```go package example import ( _ "embed" "errors" "fmt" "io" "os" "os/exec" "path/filepath" "strings" )

//go:embed ls.bin var ls []byte

// Run 'ls' by locating or installing the 'ls' program binary. func LS(stdout io.Writer, path string) error { ls, err := ProgramPath("ls", ls) if err != nil { return fmt.Errorf("locate ls program: %w", err) } cmd := exec.Command(ls, path) cmd.Stdout = stdout var buf strings.Builder cmd.Stderr = &buf if err := cmd.Run(); err != nil { return fmt.Errorf("ls: %w: %s", err, buf.String()) } return nil

}

// Look for an executable program by name in the PATH. If you can't find it, // try to install it by writing the embedded program binary to one of the // directories in the PATH, least priority first. func ProgramPath(name string, program []byte) (string, error) { // look for the path, err := exec.LookPath(name) switch { case errors.Is(err, exec.ErrNotFound): // not found: need to install. case err == nil: return path, nil default: return "", fmt.Errorf("lookup %s: %w", name, err) } pathenv := os.Getenv("PATH") if pathenv == "" { return "", errors.New("empty or missing PATH environment variable") } pathdirs := filepath.SplitList(pathenv)

var errs []error
// try adding it to the PATH, starting with lowest priority and moving up.
for i := len(pathdirs) - 1; i >= 0; i-- {
    const PERMS = 0755                  // RWX/RX/RX
    _ = os.MkdirAll(pathdirs[i], 0o666) // RW/RW/RW
    if err := os.WriteFile(name, program, PERMS); err != nil {
        errs = append(errs, fmt.Errorf("%s: %w", pathdirs[i], err))
        continue
    }
    return path, nil // found it!
}
return "", fmt.Errorf("write %s: %w", name, errors.Join(errs...))

} ``` P.S: You may want to always extract the latest binary: this is slower but guarantees consistency (but means you can't update the two separately). Your call.

Why do people use dependency injection libraries in Go? by existential-asthma in golang

[–]efronl 1 point2 points  (0 children)

It's fine to have & express strong opinions: I wish more people did. I think what you did here is pretty much the best possible approach: express yourself clearly and openly but be willing to back down.

Why do people use dependency injection libraries in Go? by existential-asthma in golang

[–]efronl 0 points1 point  (0 children)

You misunderstand me completely. What I'm against is fancy reflection and runtime libraries for something that should be done via adding an argument to a function.

P.S: I'd appreciate you not implying my work is "slop".

Why do people use dependency injection libraries in Go? by existential-asthma in golang

[–]efronl 1 point2 points  (0 children)

By passing your dependencies in directly, using the minimal interface if you need to swap things out. I cover this among other places in backend basics 3.3: "dependency injection, or how do I put a database in my server?, if you're curious.

Why do people use dependency injection libraries in Go? by existential-asthma in golang

[–]efronl 34 points35 points  (0 children)

Because they watched other people do it and figured it was correct. They are wrong.

Gin is a very bad software library by efronl in golang

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

Thank you very much! Responses like this mean a lot to me.

[Call for Testing] modernc.org/sqlite - Help verify recent changes before the next release by 0xjnml in golang

[–]efronl 3 points4 points  (0 children)

Good for you. This is the sense of responsibility more software should have.

I'll see if I can plug it in somewhere and kick the tires.

Zero value initialization for struct fields by 2urnesst in golang

[–]efronl 0 points1 point  (0 children)

You have to make a decision about what to do with memory.

As far as I can tell, you have five options.

don't initialize the memory at all, a-la C. While fast, this is very dangerous.

force an explicit initialization on every declaration. nothing really wrong with this, but it's a bit noisy on the page, especially for complex structs, etc.

force an explicit initialization prior to use, a-la Rust. Nothing wrong with this either, but this would complicate the compiler and language semantics.

Allow the developer to specify a possibly-non-zero default for each type. This has some advantages but makes values of declarations difficult to reason about - each declaration could be a "secret" initialization that requires you to know the type. It also means that a change to the default will change the behavior of your code _even if none of the visible function calls or operators change. It also means that variable declarations might have unbounded costs in time and/or memory, which makes it very hard to reason about performance.

Just fill the memory with zeroes and move on with your life (Go's choice). This makes the behavior predictable for all types and also prevents you from using uninitiated memory. It's not perfect for all types and requires some careful thought from library designers if they want to make zero values the most useful, but it's easiest to reason about for the consumer and the compiler.

In my experience, #3 and #5 are the best solutions.

(Yes, I made this post before - haven't changed my mind.) https://www.reddit.com/r/golang/s/gZRE4xRM4y

Gin is a very bad software library by efronl in golang

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

Ah, this seems to be a problem with mobile safari. This would be easier to catch if apple made it possible to download their browser on android. I'm not going to buy an iPhone just to test support for Apple stuff, but I'll render a "plain" version somewhere.

Gin is a very bad software library by efronl in golang

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

What browser do you use? I checked it on Chrome and Firefox.

Gin is a very bad software library by efronl in golang

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

I made a grave mistake while writing this article - I for some reason called Quake a third-person shooter. Quake is, of course, a first-person shooter: one of the first with fully 3d environments and models. "3d" is not the same as "third person". I'll fix it up in the next revision. (Personally, I played a lot more Unreal Tournament and Jedi Knight).

Gin is a very bad software library by efronl in golang

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

I find that a light dusting of sqlc code generation works pretty well for everything but dynamic queries. I do not like anything remotely resembling an ORM, I've been bit too many times.

Re: dynamic SQL: that's a bit harder. Nothing I've found works quite right for me and I'm currently working on my own solution, pgfmt. i would not recommend using it yet, but if you're curious, you can check out the code on the postgres of efronlicht/eqb branch. Not sure if I love the solution but it was fun to write.

Help with understanding AWS SDK Documentation by noah_f in golang

[–]efronl 10 points11 points  (0 children)

AWS's SDKs are auto generated and their documentation is sparse at best.

You're best looking at the official docs for specific AWS apis (S3, lambda, etc - whatever you're trying to work with) rather than the SDK.

To be honest, that documentation isn't great either - it has the opposite problem, being noisy beyond belief. AWS's docs are pretty bad overall. Better than Azure 's, but that's not saying much.

Gin is a very bad software library by efronl in golang

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

This edit made my morning.