From 8bf55ec35cbda2f0f0255df5da8877977eec1e73 Mon Sep 17 00:00:00 2001 From: Hau Nguyen Date: Tue, 19 Jul 2022 01:17:13 +0700 Subject: [PATCH] feat: add my mail --- docs/2022-06-08-backup.html | 2 +- docs/2022-06-08-dockerfile-go.html | 2 +- docs/2022-07-10-bootstrap-go.html | 2 +- docs/2022-07-12-uuid-or-else.html | 2 +- docs/index.html | 2 +- templates/post.html | 1 + 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/2022-06-08-backup.html b/docs/2022-06-08-backup.html index ee7dd38..bc9503b 100644 --- a/docs/2022-06-08-backup.html +++ b/docs/2022-06-08-backup.html @@ -3,4 +3,4 @@ rclone sync MyBooks remote:MyBooks -P --exclude .DS_Store # Sync from remote to local rclone sync remote:MyBooks MyBooks -P --exclude .DS_Store -

Before you use Rclone to sync to Google Drive, you should read Google Drive rclone configuration first.

The next data is my passwords and my OTPs.
These are the things which I'm scare to lose the most.
First thing first, I enable 2-Step Verification for all of my important accounts, should use both OTP and phone method.

I use Bitwarden for passwords (That is a long story, coming from Google Password manager to Firefox Lockwise and then settle down with Bitwarden) and Aegis for OTPs.
The reason I choose Aegis, not Authy (I use Authy for so long but Aegis is definitely better) is because Aegis allows me to extract all the OTPs to a single file (Can be encrypted), which I use to transfer or backup easily.

As long as Bitwarden provides free passwords stored, I use all of its apps, extensions so that I can easily sync passwords between laptops and phones.
The thing I need to remember is the master password of Bitwarden in my head.

With Aegis, I export the data, then sync it to Google Drive, also store it locally in my phone.
For safety, I also store Aegis data locally on all of my laptops (Encrypted of course).

The main problem here is the OTP, I can not store all of my OTPs in the cloud completely.
Because if I want to access my OTPs in the cloud, I should log in, and then input my OTP, this is a circle, my friends.

Recovery strategy

There are many strategies that I process to react as if something strange is happening to my devices.

If I lost my laptops, single laptop or all, do not panic as long as I have my phones.
The OTPs are in there, the passwords are in Bitwarden cloud, other data is in Google Drive so nothing is lost here.

If I lost my phone, but not my laptops, I use the OTPs which are stored locally in my laptops.

In the worst situation, I lost everything, my laptops, my phone.
The first step is to recover my SIM, then log in to Google account using the password and SMS OTP.
After that, log in to Bitwarden account using the master password and OTP from Gmail, which I open previously.

The end

This guide will be updated regularly I promise. \ No newline at end of file +

Before you use Rclone to sync to Google Drive, you should read Google Drive rclone configuration first.

The next data is my passwords and my OTPs.
These are the things which I'm scare to lose the most.
First thing first, I enable 2-Step Verification for all of my important accounts, should use both OTP and phone method.

I use Bitwarden for passwords (That is a long story, coming from Google Password manager to Firefox Lockwise and then settle down with Bitwarden) and Aegis for OTPs.
The reason I choose Aegis, not Authy (I use Authy for so long but Aegis is definitely better) is because Aegis allows me to extract all the OTPs to a single file (Can be encrypted), which I use to transfer or backup easily.

As long as Bitwarden provides free passwords stored, I use all of its apps, extensions so that I can easily sync passwords between laptops and phones.
The thing I need to remember is the master password of Bitwarden in my head.

With Aegis, I export the data, then sync it to Google Drive, also store it locally in my phone.
For safety, I also store Aegis data locally on all of my laptops (Encrypted of course).

The main problem here is the OTP, I can not store all of my OTPs in the cloud completely.
Because if I want to access my OTPs in the cloud, I should log in, and then input my OTP, this is a circle, my friends.

Recovery strategy

There are many strategies that I process to react as if something strange is happening to my devices.

If I lost my laptops, single laptop or all, do not panic as long as I have my phones.
The OTPs are in there, the passwords are in Bitwarden cloud, other data is in Google Drive so nothing is lost here.

If I lost my phone, but not my laptops, I use the OTPs which are stored locally in my laptops.

In the worst situation, I lost everything, my laptops, my phone.
The first step is to recover my SIM, then log in to Google account using the password and SMS OTP.
After that, log in to Bitwarden account using the master password and OTP from Gmail, which I open previously.

The end

This guide will be updated regularly I promise.

Feel free to ask me via email \ No newline at end of file diff --git a/docs/2022-06-08-dockerfile-go.html b/docs/2022-06-08-dockerfile-go.html index 1dd8c9d..a28914c 100644 --- a/docs/2022-06-08-dockerfile-go.html +++ b/docs/2022-06-08-dockerfile-go.html @@ -32,4 +32,4 @@ COPY . . COPY --from=builder /build/app /app ENTRYPOINT ["/app"] -

Finally, I copy app to Distroless base image. \ No newline at end of file +

Finally, I copy app to Distroless base image.

Feel free to ask me via email \ No newline at end of file diff --git a/docs/2022-07-10-bootstrap-go.html b/docs/2022-07-10-bootstrap-go.html index 685f603..fe0aaf2 100644 --- a/docs/2022-07-10-bootstrap-go.html +++ b/docs/2022-07-10-bootstrap-go.html @@ -51,4 +51,4 @@ func NewS(opts ...OptionS) *S { } return s } -

In above example, I construct s with WithA and WithB option.
No need to pass direct field inside s.

External libs

No need vendor

Only need if you need something from vendor, to generate mock or something else.

Don't use cli libs (spf13/cobra, urfave/cli) just for Go service

What is the point to pass many params (--abc, --xyz) when what we only need is start service?

In my case, service starts with only config, and config should be read from file or environment like The Twelve Factors guide.

Don't use grpc-ecosystem/grpc-gateway

Just don't.

Use protocolbuffers/protobuf-go, grpc/grpc-go for gRPC.

Write 1 for both gRPC, REST sounds good, but in the end, it is not worth it.

Don't use uber/prototool, use bufbuild/buf

prototool is deprecated, and buf can generate, lint, format as good as prototool.

Use gin-gonic/gin for REST.

Don't use gin.Context when pass context from handler layer to service layer, use gin.Context.Request.Context() instead.

If you want log, just use uber-go/zap

It is fast!

Don't overuse ORM libs, no need to handle another layer above SQL.

Each ORM libs has each different syntax.
To learn and use those libs correctly is time consuming.
So just stick to plain SQL.
It is easier to debug when something is wrong.

But database/sql has its own limit.
For example, it is hard to get primary key after insert/update.
So may be you want to use ORM for those cases.

If you want test, just use stretchr/testify.

It is easy to write a suite test, thanks to testify.
Also, for mocking, there are many options out there.
Pick 1 then sleep peacefully.

Replace go fmt, goimports with mvdan/gofumpt.

gofumpt provides more rules when format Go codes.

Use golangci/golangci-lint.

No need to say more.
Lint or get the f out!

Thanks

\ No newline at end of file +

In above example, I construct s with WithA and WithB option.
No need to pass direct field inside s.

External libs

No need vendor

Only need if you need something from vendor, to generate mock or something else.

Don't use cli libs (spf13/cobra, urfave/cli) just for Go service

What is the point to pass many params (--abc, --xyz) when what we only need is start service?

In my case, service starts with only config, and config should be read from file or environment like The Twelve Factors guide.

Don't use grpc-ecosystem/grpc-gateway

Just don't.

Use protocolbuffers/protobuf-go, grpc/grpc-go for gRPC.

Write 1 for both gRPC, REST sounds good, but in the end, it is not worth it.

Don't use uber/prototool, use bufbuild/buf

prototool is deprecated, and buf can generate, lint, format as good as prototool.

Use gin-gonic/gin for REST.

Don't use gin.Context when pass context from handler layer to service layer, use gin.Context.Request.Context() instead.

If you want log, just use uber-go/zap

It is fast!

Don't overuse ORM libs, no need to handle another layer above SQL.

Each ORM libs has each different syntax.
To learn and use those libs correctly is time consuming.
So just stick to plain SQL.
It is easier to debug when something is wrong.

But database/sql has its own limit.
For example, it is hard to get primary key after insert/update.
So may be you want to use ORM for those cases.

If you want test, just use stretchr/testify.

It is easy to write a suite test, thanks to testify.
Also, for mocking, there are many options out there.
Pick 1 then sleep peacefully.

Replace go fmt, goimports with mvdan/gofumpt.

gofumpt provides more rules when format Go codes.

Use golangci/golangci-lint.

No need to say more.
Lint or get the f out!

Thanks

Feel free to ask me via email \ No newline at end of file diff --git a/docs/2022-07-12-uuid-or-else.html b/docs/2022-07-12-uuid-or-else.html index c5a6a73..93fec15 100644 --- a/docs/2022-07-12-uuid-or-else.html +++ b/docs/2022-07-12-uuid-or-else.html @@ -1 +1 @@ -Index

UUID or else

There are many use cases where we need to use a unique ID.
In my experience, I only encouter 2 cases:

In my Go universe, there are some libs to help us with this:

First use case is trace ID, or context aware ID

The ID is used only for trace and log.
If same ID is generated twice (because maybe the possibilty is too small but not 0), honestly I don't care.
When I use that ID to search log , if it pops more than things I care for, it is still no harm to me.

My choice for this use case is rs/xid.
Because it is small (not span too much on log line) and copy friendly.

Second use case is primary key, also hard choice

Why I don't use auto increment key for primary key?
The answer is simple, I don't want to write database specific SQL.
SQLite has some different syntax from MySQL, and PostgreSQL and so on.
Every logic I can move to application layer from database layer, I will.

In the past and present, I use google/uuid, specificially I use UUID v4.
In the future I will look to use segmentio/ksuid and oklog/ulid (trial and error of course).
Both are sortable, but google/uuid is not.
The reason I'm afraid because the database is sensitive subject, and I need more testing and battle test proof to trust those libs.

What else?

I think about adding prefix to ID to identify which resource that ID represents.

Thanks

\ No newline at end of file +Index

UUID or else

There are many use cases where we need to use a unique ID.
In my experience, I only encouter 2 cases:

In my Go universe, there are some libs to help us with this:

First use case is trace ID, or context aware ID

The ID is used only for trace and log.
If same ID is generated twice (because maybe the possibilty is too small but not 0), honestly I don't care.
When I use that ID to search log , if it pops more than things I care for, it is still no harm to me.

My choice for this use case is rs/xid.
Because it is small (not span too much on log line) and copy friendly.

Second use case is primary key, also hard choice

Why I don't use auto increment key for primary key?
The answer is simple, I don't want to write database specific SQL.
SQLite has some different syntax from MySQL, and PostgreSQL and so on.
Every logic I can move to application layer from database layer, I will.

In the past and present, I use google/uuid, specificially I use UUID v4.
In the future I will look to use segmentio/ksuid and oklog/ulid (trial and error of course).
Both are sortable, but google/uuid is not.
The reason I'm afraid because the database is sensitive subject, and I need more testing and battle test proof to trust those libs.

What else?

I think about adding prefix to ID to identify which resource that ID represents.

Thanks

Feel free to ask me via email \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index 4dd404b..3ad71c4 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1 +1 @@ -Index

Index

This is where I dump my thoughts.

\ No newline at end of file +Index

Index

This is where I dump my thoughts.

Feel free to ask me via email \ No newline at end of file diff --git a/templates/post.html b/templates/post.html index b9799e9..b9ba552 100644 --- a/templates/post.html +++ b/templates/post.html @@ -14,5 +14,6 @@ Index {{.Body}} + Feel free to ask me via email