Go modules with private repositories

The following HTTP error may happen when adding a private module (repo) to the project even if your SSH keys are properly configured and you have access to the private repo. Private means it’s not a publicly open project on Github/Gitlab/etc.

warning

GONE 410

The reason for that is that the go mod tool tries to verify the module with its public checksum database, but it cannot find the module listed there (because it’s private).

To skip that check we can run the following commands in terminal:

1
2
3
export GO111MODULE=on
export GOPROXY=direct
export GOSUMDB=off

Pixel 3 Adaptive Brightness Stopped Working

Recently I noticed the adaptive brightness of my phone doesn’t work. Here is the fix:

  1. Open Settings and click Apps and notifications

  2. Click on the link See all 123 apps

  3. Find an app called Device Health Services and click it

  4. Open Storage & cache of the app and click Clear storage

  5. Click on the button Reset adaptive brightness

  6. It seems to work for the moment

SSH Local Port Forwarding

To forward requests coming to a local TCP port to another server [host:port] connected via SSH we can use a config file or direct command line arguments. To use a config file, it should be named config and placed inside the ~/.ssh folder. Here is a sample ~/.ssh/config file with some options:

1
2
3
4
5
6
Host my-ssh-connection
  Hostname 10.20.30.40
  User penkovski
  LocalForward 7070 localhost:8080
  LocalForward 7171 localhost:8181
  ControlMaster auto

This will forward all requests hitting the local (client) TCP port 7070 to the localhost:8080 on the server and all requests for local TCP port 7171 to the localhost:8181 on the server. The above configuration will be used automatically when initiating an SSH connection by the alias:

1
ssh my-ssh-connection

Update an XML node value with Go

In my humble opinion, modifying an XML node value with the Go standard xml package without describing all tags in data structures is not very intuitive. Hence this post is born. There are many ways to do it with their pros and cons. I’ll describe 2 ways. The first is simpler, but loses some XML elements like comments and possibly formatting. The other is more involved but preserves everything from the initial document, including comments and formatting.

Below is the XML document we’ll use as an example and the node we’ll modify is app>description>version. We’d like to set the version value from 1.0 to 2.0. Assume the XML file is called application.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<app>
	<!-- application description -->
	<description>
		<name>My App</name>
		<version>1.0</version>
	</description>
	<!-- developer maintaining the application -->
	<developer>
		<name>Developer Name</name>
		<contacts>
			<email>developer@example.com</email>
			<mobile>+359888888888</mobile>
		</contacts>
	</developer>
	<!-- markets where the app is distributed -->
	<market>
		<googleplay>https://googleplay.com/url</googleplay>
		<appstore>https://appstore.com/url</appstore>
	</market>
</app>

Print stack traces for hanged Go program

If a program using channels or mutexes is stuck because of synchronization problems, we can send an abort signal to kill the process and print the stack traces of currently running go routines to debug where the program might have hanged. Find the PID of the running program with ps and type:

1
kill -ABRT <PID>

JSON unmarshal of time.Duration in Go

The post describes how to unmarshal time.Duration which is not supported by the default JSON unmarshaler, but the example can be used to unmarshal any custom type.

Here is the JSON we’re unmarshaling:

1
2
3
4
{
	"addr": "https://example.com",
	"timeout": "5s",
}

We’d like to convert the 5s value to a time.Duration value corresponding to 5 seconds and get the JSON to unmarshal in the following data structure:

1
2
3
4
type connection struct {
	Addr 	string		`json:"addr"`
	Timeout time.Duration 	`json:"timeout"`
}

One way to do it is to implement the Unmarshaler interface and handle the conversion in our UnmarshalJSON function.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Unmarshaler is the interface implemented by types  
// that can unmarshal a JSON description of themselves.  
// The input can be assumed to be a valid encoding of  
// a JSON value. UnmarshalJSON must copy the JSON data  
// if it wishes to retain the data after returning.  
//  
// By convention, to approximate the behavior of Unmarshal itself,  
// Unmarshalers implement UnmarshalJSON([]byte("null")) as a no-op.  
type Unmarshaler interface {  
   UnmarshalJSON([]byte) error  
}

Below is the complete example. We unmarshal the JSON into a temprary structure where 5s is a standard string. Then we convert the string to time.Duration vaue and set it in our structure.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package mypackage

import(
	"json/encoding"
	"time"
)

type connection struct {
	Addr 	string 		  `json:"addr"`
	Timeout time.Duration `json:"timeout"`
}

func (c *connection) UmarshalJSON(data []byte) (err error) {
	var tmp struct {
		Addr 	string
		Timeout string
	}
	if err = json.Unmarshal(data, &tmp); err != nil {
		return err
	}

	c.Addr = tmp.Addr
	c.Timeout, err = time.ParseDuration(tmp.Timeout)
	return err
}

Go program design for testing with counterfeiter

counterfeiter is a command-line tool for generating fake implementation of Go interfaces.

One of the best things we can do when writing Go programs is to design our components’ dependencies to be based on local interfaces. By local I mean interfaces which are needed and defined by a given component. Consider the following example: we have a http server, a service component and a database dependency.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
package main

func main() {
	// initialize some kind of database
	db := storage.New()
	
	// our service depends on a database
	svc := service.New(db)
	
	http.HandleFunc("/example", svc.Example)
	log.Fatal(http.ListenAndServe(":8080", nil))
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
package storage

type DB struct {}

type Data struct {}

func New() *DB {
	return &DB{}
}

func (db *DB) SomeData() (*Data, error) {
	... // return data from database
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package service

type Storage interface {
	SomeData() (*storage.Data, error)
}

type Data struct{
	Value int
}

type Service struct {
	db Storage
}

func New(db Storage) *Service {
	return &Service{db:db}
}

func (s *Service) Example(w http.ResponseWriter, r *http.Request) {
	// do something that requires using the database
	data, err := s.db.SomeData()
	if err != nil {
		...
	}

	// do something with data and write response
	...
}

The service component has a database dependency. It may be any kind of external object - client to another service, a cache/database, message queue, whatever. This dependency is expressed as an interface inside the service package. In effect, the service is telling its initialiser: when you create me, please give me an object which implements my service.Storage interface, cause that’s what I need to execute my functions.

This design has some nice benefits. The service component doesn’t know and care how the storage dependency is implemented. All it knows and cares about is that it has a SomeData() (*storage.Data, error) function. We can supply whatever object we wish to the service, as long as it implements the interface.

Here comes the counterfeiter

Java Random within Range

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// randInt generates pseudo-random number 
// in the range [min...max] inclusive.
public static int randInt(int min, int max) 
{
    Random random = new Random();

    // nextInt is exclusive of the top value, 
    // so add 1 to make it inclusive
    return random.nextInt((max - min) + 1) + min;
}

Git SSH Authentication

If we want to use different authentication keys for a particular Git repo, we can edit the config file of the repo and add the sshCommand setting.

Navigate to the repository’s Git configuration directory:

1
cd /path/to/repo/.git

In the folder there’s a file called config. We are interested in the core section. To use a particular SSH key for Git, we would write the command as shown below. Replace the name of the key file with your own.

1
2
3
4
5
[core]
	...
	...
	...
	sshCommand = ssh -i ~/.ssh/my_custom_git_key

Perspective on Computer Hardware Advancements

note

Excerpt from The Clean Coder by Robert Martin

“One of the first machines I ever wrote programs for was a PDP-8/I. This machine had a 1.5-microsecond cycle time. It had 4096 12-bit words in core memory. It was the size of a refrigerator and consumed a significant amount of electrical power. It had a disk drive that could store 32K of 12-bit words, and we talked to it with a 10-character-per-second teletype. We thought this was a powerful machine, and we used it to work miracles.

I just bought a new Macbook Pro laptop. It has a 2.8GHz dual core processor, 8GB of RAM, a 512GB SSD, and a 17-inch 1920x1200 LED screen. I carry it in my backpack. It sits on my lap. It consumes less than 85 watts.

My laptop is eight thousand times faster, has two million times more memory, has sixteen million times more offline storage, requires 1% of the power, takes up 1% of the space, and costs one twenty-fifth of the price of the PDP-8/I.”