Category Archives: Uncategorized

How to transfer files to many servers

Before making a decision, there are to clarify and consider from different perspective.

1 size of the file? 5K? 5G 5T?

2. Frequency? one time? once a day? or more?

3. If more than one time, how different between those files? incremental change or completely different?

4. Any expectation? as fast as possible? or intrusively to other applications?

5. how reliable?

Technical questions:

  1. bottleneck: network topology&bandwidth, disk speed, memory size,
  2. failure handling. retry,, version conflict

what to optimization, time or others?

break into pieces to reduce wait time?

integrity and consistency?

DSM 7.0 haugene transmission with openvpn

docker container stopped working after upgrade to DSM 7.0 with Synology NAS.

This is due to tighten permission in DSM 7.0. It can be fixed by enabling container capacity “NET_ADMIN”. The problem is the DSM docker UI does not support this feature. This can be easier done in portainer, another open source container manager.

Here is the steps to deploy portainer as a container. This requires ssh into DSM 7.0

# ssh into your nas as administrator
ssh nas -l admin

# create  dir for holding portainer config
sudo mkdir  /volume1/docker/portainer

# deploy portainer as a container thru docker, please ensure ports still available
sudo docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /volume1/docker/portainer:/data portainer/portainer-ce

If everything goes thru fine, portainer container should be up and running. This can be verified in dsm docker ui as well.

connect to portainer at http://nas:9000 in browser.

Set up initial password

Select connect to “docker”

go to containers:

You are supposed to see all your containers, haugene container should be stopped state. (one of mine is up since screenshot is taken after everything fixed.)

Please focus on container haugene-transimission-openvpn3, this is the original one that stopped working after upgrade to dsm 7.0.

open “haugene-transimission-openvpn3”

Click “Duplicate/Edit” button on the top right, then you will have an opportunity to re-config a copy of original container.

change the name so that you can tell this is a new container..

Click “Advanced container settings”

Disable “Privileged mode” in “Runtime & Resources” tab.

Enable “NET_ADMIN” in Capability tab.

Click “Deploy the container” button, then you are done. It should be up and running in a few secs.

Verify if traffics are going thru vpn at http://checkmyip.torrentprivacy.com/

Goland issue with gcp library

import google.golang.org/api/compute/v1

compute.NewService(....)

IDE is having issue paring the generated library golang source code.


solution:
Go to help menu and open "edit custom properties"
increase or add the following "idea.max.intellisense.filesize"
problem should be gone after restarting IDE.
----------------------------
# custom GoLand properties

idea.max.intellisense.filesize=999999

Cyclic Dependency in Golang

Example:

A import B

B import A

X import A or B

Solution?

Abstract common things into an interface “I”.

Move I into it’s own package.

i.I

A return i.I

B import A & i.I, B create a implementation of i.I and set it on A

A <- B (so B only depends on B and I.i , A does not depend on B)

X ask A to return B

Golang range iterator of pointer

It’s tricky to using pointer in range iterator.

Please beware variable “hostStatus” is a pointer that’s been reused in each iteration. the location of hostStatus will be the same although it points to a different struct in each iteration.

It may cause duplicated values in the final results, beware!

package main

import (
	"fmt"
	"strings"

)


type HostStatus struct {
	Name    string
	Status  string
	Message string
}

func main() {
	value := []HostStatus{HostStatus{"1","ok","test1"}, HostStatus{"2","ok","test2"}, HostStatus{"3","ok","test3"}}
	fmt.Printf("value = %v\n", value)
	hostnameToStatus := map[string]HostStatus{}
	hostnameToStatusP := map[string]*HostStatus{}
	hostnameToStatusP2 := map[string]*HostStatus{}
	for k, hostStatus := range value {
		hostnameToStatus[hostStatus.Name] = hostStatus
		hostnameToStatusP[hostStatus.Name] = &value[k]
		hostnameToStatusP2[hostStatus.Name] = &hostStatus
		fmt.Printf("%s , p= %p\n", hostStatus.Name, &hostStatus)
	}
	fmt.Print("--1--\n")
	for k, v := range hostnameToStatus {
		fmt.Printf("%s = %s\n", k, v)
	}
	fmt.Print("--2--\n")
	for k, v := range hostnameToStatusP {
		fmt.Printf("%s = %s\n", k, v)
	}
	fmt.Print("--3--\n")
	for k, v := range hostnameToStatusP2 {
		fmt.Printf("%s = %v\n", k, v)
		fmt.Printf("%s = %p\n", k, &v)
	}

	successfulChildHostList := []string{}
	merged := []HostStatus{}
	for _, hostStatus := range hostnameToStatusP {
		merged = append(merged, *hostStatus)
		if strings.EqualFold(hostStatus.Status, "yes") {
			successfulChildHostList = append(successfulChildHostList, hostStatus.Name)
		}
	}
	fmt.Print("-----------\n")
	fmt.Printf("merged = %v\n", merged)
	fmt.Printf("successfulChildHostList = %v\n", successfulChildHostList)

}

Results, see the 3rd one with duplicated values.:

value = [{1 ok test1} {2 ok test2} {3 ok test3}]
1 , p= 0xc000068210
2 , p= 0xc000068210
3 , p= 0xc000068210
--1--
3 = {3 ok test3}
1 = {1 ok test1}
2 = {2 ok test2}
--2--
1 = &{1 ok test1}
2 = &{2 ok test2}
3 = &{3 ok test3}
--3--
1 = &{3 ok test3}
1 = 0xc00000e030
2 = &{3 ok test3}
2 = 0xc00000e030
3 = &{3 ok test3}
3 = 0xc00000e030
-----------
merged = [{1 ok test1} {2 ok test2} {3 ok test3}]
successfulChildHostList = []

Can done() be used multiple times in golang context?

Yes done() can be used as many times as you want.

here is an example:

package main

import (
        "context"
        "time"
)
func f(ctx context.Context) {
	for i:=0;i<10;i++{
		select {
		case <- ctx.Done():
			println("canceled")
		default:
			println(".")

		}

		time.Sleep(1*time.Second)
	}
	println("f exit")
}

func main() {

        ctx, cancel := context.WithCancel(context.Background())
        go f(ctx)
        time.Sleep(3*time.Second)
        println("call ctx cancel()")
        cancel()
        time.Sleep(10*time.Second)
        println("exit")
}

results:

go run cancel.go
.
.
.
call ctx cancel()
canceled
canceled
canceled
canceled
canceled
canceled
canceled
f exit
exit

See “canceled” got returned constantly after context was canceled.

Fix Sony WH-1000XM3

(It’s all at your own responsibility)

Used for about a year but one side suddenly stopped working. Sound may go back when tapping the cover. More likely there is short circuit inside.

Following video to open the left or right with no more sound :

  1. take out the cushion
  2. take out the foam covering speaker
  3. take out 4 screws from speaker side
  4. take out the back cover. (be slow, there are wires connected between cover and circuit board)

Once opened, I noticed bunch of wires are put together by two pieces of black tapes. Carefully take out the tape without breaking any wire. Gentle moving the wires while playing sounds on the side having issue to identify which wire is broken. In my case, wires are all good, but I found the end portion of the wire soldered to board may touch circuit board in some cases. So I inserted the original black tape underneath the wires to keep them from touching the board and another tape to fix them. Moving wire or tapping around will not cause any issue after this. Put everything back, done! Hopefully this may help more people.