Skip to main content

Get the Reddit app

Scan this QR code to download the app now
Or check it out in the app stores
r/golang icon
r/golang icon

r/golang

members
online


Who's Hiring? - June 2024

This post will be stickied at the top of until the last week of June (more or less).

Please adhere to the following rules when posting:

Rules for individuals:

  • Don't create top-level comments; those are for employers.

  • Feel free to reply to top-level comments with on-topic questions.

  • Meta-discussion should be reserved for the distinguished mod comment.

Rules for employers:

  • To make a top-level comment you must be hiring directly, or a focused third party recruiter with specific jobs with named companies in hand. No recruiter fishing for contacts please.

  • The job must involve working with Go on a regular basis, even if not 100% of the time.

  • One top-level comment per employer. If you have multiple job openings, please consolidate their descriptions or mention them in replies to your own top-level comment.

  • Please base your comment on the following template:

COMPANY: [Company name; ideally link to your company's website or careers page.]

TYPE: [Full time, part time, internship, contract, etc.]

DESCRIPTION: [What does your team/company do, and what are you using Go for? How much experience are you seeking and what seniority levels are you hiring for? The more details the better.]

LOCATION: [Where are your office or offices located? If your workplace language isn't English-speaking, please specify it.]

ESTIMATED COMPENSATION: [Please attempt to provide at least a rough expectation of wages/salary.If you can't state a number for compensation, omit this field. Do not just say "competitive". Everyone says their compensation is "competitive".If you are listing several positions in the "Description" field above, then feel free to include this information inline above, and put "See above" in this field.If compensation is expected to be offset by other benefits, then please include that information here as well.]

REMOTE: [Do you offer the option of working remotely? If so, do you require employees to live in certain areas or time zones?]

VISA: [Does your company sponsor visas?]

CONTACT: [How can someone get in touch with you?]


The 2024 Ebitengine Game Jam has started! The 2024 Ebitengine Game Jam has started!

The Ebitengine Game Jam is a 2-week event starting on 15 June organised by the Ebitengine community for anyone to showcase the Ebitengine game library by building games based on a secret theme.

The secret theme this year has been announced, it's: BUILDING 🏗️🍤 (including build, build up, builder, etc.)! Feel free to interpret it figuratively or completely literally, it's up to you, so get creative! For more details and to join in, see: itch.io/jam/ebitengine-game-jam-2024


Any Patterns/Strategies for html/template and form data management? Any Patterns/Strategies for html/template and form data management?

I'm mostly a backend developer and I'm creating a small web application (less than 50 pages) using html/template (the frontend doesn't require a lot of interactivity either, so html/template suits quite well).

When I started putting everything together I followed the simple code examples I saw out there, where the famous 'data' struct is declared on the fly, everything needed to render the template was shoved in there, and then passed on to the 'Execute' function.

Is that really the best way to do this? As the page gets more sophisticated the code starts looking more and more ugly with an ever bigger 'data' struct.

When dealing with forms, for example, you need to preserve the form data in between posts (if server-side validation is not successful), include validation errors, plus whatever other flags and data is needed to render the rest of the template. Once form validation is successful you need to translate the form data into whatever structs and functions you've implemented for triggering additional business logic and/or persistence logic.

I tried creating explicit structs (like 'UserForm', where I declare all the form fields, and 'UserFormErrors' where I have a set of string fields with errors that may be generated while validating the form). It certainly makes the web handler function cleaner, and declaring all the structs beforehand also make it easier to compare struct field names against the variable names you see referenced on the template. But is this the best way to go? Something tells me I'm missing a simpler way to do this...


Godocx - Go library for reading and writing Microsoft Docx Godocx - Go library for reading and writing Microsoft Docx
show & tell

First beta release of Godocx is out now. Basic functions has been implemented.

You can

  • Add paragraph, headings with different styles

  • Add picture

  • Add table with different styles

  • Add bullet/number list

  • You can open existing docx and modify or create docx from scratch

There are more functions and elements has yet to be implemented.

Github Repository



Simulating a static/class method, is this the right approach? Simulating a static/class method, is this the right approach?
newbie

I'm just starting with Go, and coming from Python I'm having to twist my brain a little bit to get my grips about OOP here.

I have an User struct, and a GetUser function. I'd like to be able to call User.Get instead of GetUser, as it feels slightly more orderly. This is what I have right now:

func (User) Get(apiKey string) (user *User, err error) {
	return GetUser(apiKey)
}

And now I can call User{}.Get("123").

This works, but is this idiomatic Go, or just a workaround?




Going from Development to Production with a simple gitops all golang setup Going from Development to Production with a simple gitops all golang setup

This is the stack I use.

It takes the pain out of doing lots of development quickly with a gitops style of development without needing K8, docker and heavy stuff.

Task and Task-UI

I am using Task and Task-ui and runner

https://github.com/titpetric/task-ui

Task-UI ONLY works with Docker and I am planning to modify it to work with Runner ( see below ).

There is nothing wrong with Docker, but I find I just dont need it.

Task is where you can build workflows easily.

Is also replaced the GitHub actions, with the GitHub actions being a very simple standard template that just installs Task and then calls Task. So everything that you run locally is the same as what is run on Github Actions. Its DRY, and flexible so you can also run your Task on exotic hardware that Github does not support too.

runner

https://github.com/cirello-io/runner is able to run many processes on any OS and also can run clusters of process, like when you need 3 of something for clustering. I run it locally and in Production.

It's 100% golang and just needs a ProcFile and a .ENV, so its very simple but also can do what docker and docker-compose can do.

It has a real time GUI, so I can see everything happening on all servers both locally and remotely. You can all the processes running.

It also has a decent waiter, so that you can declare that X has to wait for Y.

It has full supervisions trees, which allows it to do what docker compose does.

I have been using this for 6 months in Production and it's been fast and easy and stable.

package management

Then there is aqua for package management. This is 100% golang and works on All desktops.

It allows me to declare a binary package I need and keep it updated.

https://github.com/aquaproj/aqua

https://github.com/aquaproj/aqua-registry/tree/main/pkgs has a huge list of packages that is growing all the time.

Deploy

I can then deploy to fly.io

Runner can run things on fly.io just fine.

You can also deploy this to any cloud, because of the nature of it.

Fly.io does autoscaling for you, Or you can also write your own custom scheduling for really large and complex things.

I need to deploy at the edge ad so use Cloudflare tunnel to expose it easily. This is free with Cloudflare. At the Edge Runner and aqua work fine without Docker on any desktops and servers.

CI / CD

With all this, its means my Github Actions are all identical for each project. It's really just a GitHub action that installs golang and task and calls Task to build and package my stuff to Aqua ( binaries ) , Docker Registry ( docker images ) that pull in the binaries from the Aqua registry at build time.

Running Aqua Registry on Fly.io is easy, along with its nice GUI and CLI.

https://github.com/aquaproj/aqua-registry/blob/main/docker/Dockerfile



Am I the only one who thinks channels are the obvious choice for iterators? Am I the only one who thinks channels are the obvious choice for iterators?

In regards to the new 'iterators' coming in Go 1.23, I stumbled upon some blog posts and chatter on social media talking about how this is an unnecessary language change. I was somewhat aware of the proposal and thought the func(func(T)bool) bool was a bit odd but after seeing this, I started investigating further and contributing to the discussion on https://github.com/golang/go/issues/61897

I've always thought channels are the obvious choice for representing iterators (as they represent a stream, queue or sequence of values), naturally I assumed there must be a good reason why the language had to change the spec in order to support iterators (instead of adding compiler optimisations for channels to support this, I've even gone into some detail on how this could be implemented efficiently).

The reaction I've received, however, is bizarre? I've been told it's too late to comment on this, it's already been decided. That channels must not be used for this (technically they can be used as iterators). Instead Go is adding special case functions to the language spec and a special case package iter just to support the same language semantics as receive-only channels?

I've always considered Go (and the community) to be very cautious about making languages changes, not to add duplicate ways of representing the same thing. Pushing a cohesive and simple design. I'm curious, is it just me feeling like there is a major shift in principles here and is there anybody else who has had a look at this and thought the built-in channels are the obvious answer here?



TView and widget sizes? TView and widget sizes?

OK, I've got a basic TView app that creates three items -- on the top is a TextView, and below it, there are two items in a horizontal Flex with a text entry on the left and a submit button on the right... BUT.....

package main

import (
"github.com/rivo/tview"
)

func main() {
app := tview.NewApplication()

// Console at the top
console := tview.NewTextView()
console.SetTitle(" Chicken3000: What's going on at the farm ")
console.SetBorder(true)

// Input field
inputField := tview.NewInputField()
inputField.SetLabel(" Enter a command: ")
inputField.SetBorder(true)

// Button to the right
button := tview.NewButton("Submit")
// Horizontal flex for the inputField and button
flexBottom := tview.NewFlex().
AddItem(inputField, 0, 1, true).
AddItem(button, 0, 1, false)

// Vertical flex for console and the horizontal flex
flex := tview.NewFlex().SetDirection(tview.FlexRow).
AddItem(console, 0, 1, false).
AddItem(flexBottom, 0, 1, true)

if err := app.SetRoot(flex, true).Run(); err != nil {
panic(err)
}
}

The problem is, the text entry and buttons are huge. I want the text entry field to take about about 80% of the line from the left, and a small button on the right. Also, the text entry field should be multi-line if I can. What did I do wrong?


Simple Go CRUD web app Simple Go CRUD web app

https://github.com/Big-Mike-Edahow/ThePagesOfYore

Over the past several months I have been learning how to program in Go by reading articles and blog posts, as well as ebooks and tutorials. This is my attempt at a simple Go CRUD web app. I tried to keep things simple by not using any frameworks and only using one third party dependency.

It seems that many tutorials and books will go from Hello World to something really complicated, with nothing in between. Others would give the routes on the back-end, with no front-end to go along with it. That frustrated me.

Hopefully this helps someone out.

Any comments, advice or tips would be welcome.





Confused about slices inner workings Confused about slices inner workings
help

I started learning go fairly recently. While reading Arrays, slices (and strings): The mechanics of 'append', I came across two intriguing examples (notice use of pointers):

type path []byte

func (p path) ToUpper() {
    for i, b := range p {
        if 'a' <= b && b <= 'z' {
            p[i] = b + 'A' - 'a'
        }
    }
}

func main() {
    pathName := path("/usr/bin/tso")
    pathName.ToUpper()
    fmt.Printf("%s\n", pathName) // /USR/BIN/TSO
}
type path []byte

func (p *path) TruncateAtFinalSlash() {
    i := bytes.LastIndex(*p, []byte("/"))
    if i >= 0 {
        *p = (*p)[0:i]
    }
}

func main() {
    pathName := path("/usr/bin/tso") // Conversion from string to path.
    pathName.TruncateAtFinalSlash()
    fmt.Printf("%s\n", pathName) // /usr/bin
}

I am confused about why the former doesn't need to use a pointer receiver, and latter does. If I understood correctly, one modifies the original array, therefore not needing a pointer, and the other one modifies the slice itself (referred as the sliceHeader in the article) ?

Thank you:)


Missing Golang Tutorials Missing Golang Tutorials

Hey guys, i hope youre doing well

I was looking for good visual content to learn about pointers in golang, and i remembered a youtube video that i once saw about the topic, it was from a asian/half asian girl, but i cant find it anywhere.

She had really good explanations about the topics, and even got cool draws and animations to explain the concepts of pointers etc. Im new to Go, and i dont know if she is known by the go community, but her content was by far the one that most got into my brain, probably because it was really visual.

Do you guys make any idea of who she is? and if yes, is there anywhere else to find her content?





Help understanding correct usage of ticker Help understanding correct usage of ticker
help

I am trying to implement some sort of rate limiter for one of my loops. While researching ways to do it, I came across ticker. Would love it if someone can review my implementation/pseudo code... I am not sure if I really understand how it works.

Context: I am sending some emails via SES to my users, and I need to stay within the mails/second limit.

Implementation:

ticker := time.NewTicker(100 * time.Millisecond) // 10 mails/second
defer ticker.Stop()

for _, job := range completed_jobs {
	// query db for job owner and users "watching" the job, store in a variable recipients
	for _, recipient := range recipients{
		// generate email content from template
		<-ticker.C // Wait for the ticker
		go MailClient().Send(message)
	}
}

I am assuming, ticker.Stop() is called when the outer loop completes. Please suggest alternatives if there is a better way to do this. TIA.


Ecoflow metrics exporter Ecoflow metrics exporter

I have two Ecoflow devices (River 2 and Delta 2) and it's frustrating that official app doesn't provide history metrics. Also the app doesn't show a lot of metrics which might be interested for end user (like input/output voltage, temperature, etc). That's why I've implemented two libraries:

  1. go-ecoflow - to provide some basic API to get metrics from Ecoflow devices (via REST API). Github: https://github.com/tess1o/go-ecoflow . Currently there are two main API: list all devices linked to the account and get all metrics for the device. The REST API provided by Ecoflow is tricky in terms of SIGN header - the logic to calculate it is pretty complex (documentation https://developer-eu.ecoflow.com/us/document/introduction ). I might implement change Ecoflow settings via REST API in sometime. Currently I don't have any use case for this.

  2. go-ecoflow-exporter - Prometheus exporter. It uses the abovementioned library to access the API. The metrics are sent to Prometheus and then rendered in Grafana. Github repository: https://github.com/tess1o/go-ecoflow-exporter

Screenshots (not allowed in this sub-reddit) and all instructions are on Github: https://github.com/tess1o/go-ecoflow-exporter

The inspiration and Grafana dashboard is taken from this github repository: https://github.com/berezhinskiy/ecoflow_exporter . It is implemented in Python using MQTT.