Skip to content

Instantly share code, notes, and snippets.

View knadh's full-sized avatar

Kailash Nadh knadh

View GitHub Profile
@knadh
knadh / unix-to-time.go
Created July 1, 2022 07:36
Convert a unix (milli) timestamp to year, month, day ... without using the standard library
package main
import (
"fmt"
"time"
)
func main() {
fmt.Println(unixToTime(time.Now().UnixMilli()))
}
@knadh
knadh / numbers-to-words.go
Created June 12, 2022 08:22
Simple algorithm for converting numbers to English words (Golang)
package main
import (
"fmt"
)
var (
ones = []string{
"zero", "one", "two", "three", "four",
"five", "six", "seven", "eight", "nine",
#!/usr/bin/env bash
DATABASE_URL="postgres://MyPostgresUser:MyPostgresPassword@192.168.0.1:5432/MyPostgresDB"
# `cut` is used to cut out the separators (:, @, /) that come matched with the groups.
DATABASE_USER=$(echo $DATABASE_URL | grep -oP "postgres://\K(.+?):" | cut -d: -f1)
DATABASE_PASSWORD=$(echo $DATABASE_URL | grep -oP "postgres://.*:\K(.+?)@" | cut -d@ -f1)
DATABASE_HOST=$(echo $DATABASE_URL | grep -oP "postgres://.*@\K(.+?):" | cut -d: -f1)
DATABASE_PORT=$(echo $DATABASE_URL | grep -oP "postgres://.*@.*:\K(\d+)/" | cut -d/ -f1)
@knadh
knadh / flatten_test.go
Last active June 9, 2021 10:52
Benchmark of flattening nested maps ({ "parent": { "child": 123 }}` -> `{ "parent.child": 123 }): Recursion vs. iteration
package main
import (
"encoding/json"
"strings"
"testing"
)
var nested map[string]interface{}
@knadh
knadh / go-redis-struct-scan.go
Last active January 24, 2021 10:06
A Redis reply to struct scanner for go-redis/redis
package cacheman
import (
"errors"
"fmt"
"reflect"
"strconv"
"strings"
)
@knadh
knadh / listmonk-upgrade-v0.7.0-alpha.sql
Created July 26, 2020 15:06
Schema changes to upgrade to listmonk v0.7.0-alpha
ALTER TABLE media DROP COLUMN width, DROP COLUMN height;
ALTER TABLE media ADD COLUMN provider TEXT NOT NULL;
DROP TABLE IF EXISTS settings CASCADE;
CREATE TABLE settings (
key TEXT NOT NULL UNIQUE,
value JSONB NOT NULL DEFAULT '{}',
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
DROP INDEX IF EXISTS idx_settings_key; CREATE INDEX idx_settings_key ON settings(key);
INSERT INTO settings (key, value) VALUES
@knadh
knadh / go-graceful-reload.go
Last active July 14, 2020 05:30
Example of gracefully shutting down and re-loading / restarting a Go app on SIGHUP retaining the same PID
// program
package main
import (
"fmt"
"log"
"os"
"os/signal"
"syscall"
"time"

Unable to get cluster admin: kafka: controller is not available

If you get this error and don't want to waste hours trying to debug why kaf is unable to communicate with a Kafka cluster, make sure you have an entry in the hosts file for the system's hostname that resolves to self (127.0.0.1), if your cluster is running locally.

@knadh
knadh / nats-cluster-multiple-publisher-failover.md
Created March 21, 2019 08:02
Running multiple active publishers on a NATS cluster for failover avoding message duplication

Running multiple active publishers on a NATS cluster for failover while avoding message duplication

NATS is an excellent, clustered, full-mesh PubSub messaging system, highly performant and a cakewalk to setup. Full mesh means every node (servers and clients) knows about every other node, which is great, but makes it tricky to have multiple publishers on hot standby, for high availability of publishers (not the NATS network), while avoiding duplicate pubs.

Here --no-advertise comes in handy if we're willing to sacrifice the automatic meshing and discovery mechanism. This may be acceptable in setups where only a fixed set of NATS servers run in a cluster and whose addresses (either IPs or hostnames) are known.

--no-advertise

The gnatsd --no-advertise flag makes a NATS server not advertise itself automatically to the mesh. For other nodes to discover --no-advertise nodes, the --routes have to be explicitly specified. If there are N servers, there should be N routes.

@knadh
knadh / redis-protocol.go
Created February 16, 2019 10:14
Go function for generation Redis raw protocol for importing with redis-cli --pipe
package main
import (
"fmt"
"bytes"
"strconv"
)
// toRedisProto converts a Redis command, represented by a slice of
// bytes, where each element of the slice represents a chunk of the