diff --git a/docs/2022-07-10-bootstrap-go.html b/docs/2022-07-10-bootstrap-go.html index 8560b00..5320c32 100644 --- a/docs/2022-07-10-bootstrap-go.html +++ b/docs/2022-07-10-bootstrap-go.html @@ -224,9 +224,9 @@ internal Example:
func main() {
- s := NewS(WithA(1), WithB("b"))
- fmt.Printf("%+v\n", s)
+ func main() {
+ s := NewS(WithA(1), WithB("b"))
+ fmt.Printf("%+v\n", s)
}
type S struct {
@@ -236,22 +236,22 @@ internal
type OptionS func(s *S)
-func WithA(a int) OptionS {
+func WithA(a int) OptionS {
return func(s *S) {
s.fieldA = a
}
}
-func WithB(b string) OptionS {
+func WithB(b string) OptionS {
return func(s *S) {
s.fieldB = b
}
}
-func NewS(opts ...OptionS) *S {
+func NewS(opts ...OptionS) *S {
s := &S{}
for _, opt := range opts {
- opt(s)
+ opt(s)
}
return s
}
@@ -292,19 +292,19 @@ internal
Example:
- eg, egCtx := errgroup.WithContext(ctx)
+ eg, egCtx := errgroup.WithContext(ctx)
-eg.Go(func() error {
+eg.Go(func() error {
// Do some thing
return nil
})
-eg.Go(func() error {
+eg.Go(func() error {
// Do other thing
return nil
})
-if err := eg.Wait(); err != nil {
+if err := eg.Wait(); err != nil {
// Handle error
}
@@ -346,27 +346,27 @@ internal
var bufPool = sync.Pool{
New: func() any {
- return new(bytes.Buffer)
+ return new(bytes.Buffer)
},
}
-func MarshalWithoutEscapeHTML(v any) ([]byte, error) {
- b, ok := bufPool.Get().(*bytes.Buffer)
+func MarshalWithoutEscapeHTML(v any) ([]byte, error) {
+ b, ok := bufPool.Get().(*bytes.Buffer)
if !ok {
return nil, ErrBufPoolNotBytesBuffer
}
- b.Reset()
- defer bufPool.Put(b)
+ b.Reset()
+ defer bufPool.Put(b)
- encoder := json.NewEncoder(b)
- encoder.SetEscapeHTML(false)
- if err := encoder.Encode(v); err != nil {
+ encoder := json.NewEncoder(b)
+ encoder.SetEscapeHTML(false)
+ if err := encoder.Encode(v); err != nil {
return nil, err
}
- result := make([]byte, b.Len())
- copy(result, b.Bytes())
+ result := make([]byte, b.Len())
+ copy(result, b.Bytes())
return result, nil
}
@@ -391,13 +391,13 @@ internal
// Ptr takes in non-pointer and returns a pointer
-func Ptr[T any](v T) *T {
+func Ptr[T any](v T) *T {
return &v
}
Return zero value:
- func Zero[T any]() T {
+ func Zero[T any]() T {
var zero T
return zero
}
@@ -584,8 +584,8 @@ internal
Remember to free resources after parse multipart form:
defer func() {
- if err := c.Request.MultipartForm.RemoveAll(); err != nil {
- fmt.Println(err)
+ if err := c.Request.MultipartForm.RemoveAll(); err != nil {
+ fmt.Println(err)
}
}()
@@ -723,14 +723,14 @@ internal
Example:
- func (c *client) HSetWithExpire(ctx context.Context, key string, values []any, expired time.Duration) error {
- cmds := make([]redis.Cmder, 2)
+ func (c *client) HSetWithExpire(ctx context.Context, key string, values []any, expired time.Duration) error {
+ cmds := make([]redis.Cmder, 2)
- if _, err := c.Pipelined(ctx, func(pipe redis.Pipeliner) error {
- cmds[0] = pipe.HSet(ctx, key, values...)
+ if _, err := c.Pipelined(ctx, func(pipe redis.Pipeliner) error {
+ cmds[0] = pipe.HSet(ctx, key, values...)
if expired > 0 {
- cmds[1] = pipe.Expire(ctx, key, expired)
+ cmds[1] = pipe.Expire(ctx, key, expired)
}
return nil
@@ -743,7 +743,7 @@ internal
continue
}
- if err := cmd.Err(); err != nil {
+ if err := cmd.Err(); err != nil {
return err
}
}
@@ -884,10 +884,10 @@ internal
Don't cast enum:
// Bad
-a := cast.ToInt32(servicev1.ReasonCode_ABC)
+a := cast.ToInt32(servicev1.ReasonCode_ABC)
// Good
-a := int32(servicev1.ReasonCode_ABC)
+a := int32(servicev1.ReasonCode_ABC)
diff --git a/docs/2022-07-31-experiment-go.html b/docs/2022-07-31-experiment-go.html
index ca21a6f..f24f1ea 100644
--- a/docs/2022-07-31-experiment-go.html
+++ b/docs/2022-07-31-experiment-go.html
@@ -83,8 +83,8 @@
}
// c is Client
-c.GetUser()
-c.RemoveAccount()
+c.GetUser()
+c.RemoveAccount()
Try:
@@ -104,8 +104,8 @@
}
// c is Client
-c.User.Get()
-c.Account.Remove()
+c.User.Get()
+c.Account.Remove()
The difference is c.GetUser()
->
diff --git a/docs/2022-07-31-sql.html b/docs/2022-07-31-sql.html
index b3212b6..f59f83b 100644
--- a/docs/2022-07-31-sql.html
+++ b/docs/2022-07-31-sql.html
@@ -511,6 +511,15 @@
>
+
+
+
diff --git a/docs/2022-12-25-go-test-asap.html b/docs/2022-12-25-go-test-asap.html
index a1e7e31..cddb8fe 100644
--- a/docs/2022-12-25-go-test-asap.html
+++ b/docs/2022-12-25-go-test-asap.html
@@ -141,25 +141,25 @@
verifyService VerifyService
}
-func (s *service) Upload(ctx context.Context, req Request) error {
+func (s *service) Upload(ctx context.Context, req Request) error {
// I simplify by omitting the response, only care error for now
- if err := s.verifyService.Verify(req); err != nil {
+ if err := s.verifyService.Verify(req); err != nil {
return err
}
- if err := s.minio.Put(req); err != nil {
+ if err := s.minio.Put(req); err != nil {
return err
}
- if err := s.redis.Set(req); err != nil {
+ if err := s.redis.Set(req); err != nil {
return err
}
- if err := s.db.Save(req); err != nil {
+ if err := s.db.Save(req); err != nil {
return err
}
- if err := s.logService.Save(req); err != nil {
+ if err := s.logService.Save(req); err != nil {
return err
}
@@ -184,12 +184,12 @@
s service
}
-func (s *ServiceSuite) SetupTest() {
+func (s *ServiceSuite) SetupTest() {
// Init mock
// Init service
}
-func (s *ServiceSuite) TestUpload() {
+func (s *ServiceSuite) TestUpload() {
tests := []struct{
name string
req Request
@@ -206,15 +206,15 @@
}
for _, tc := range tests {
- s.Run(tc.name, func(){
+ s.Run(tc.name, func(){
// Mock all error depends on test case
if tc.verifyErr != nil {
- s.verifyService.MockVerify().Return(tc.verifyErr)
+ s.verifyService.MockVerify().Return(tc.verifyErr)
}
// ...
- gotErr := s.service.Upload(tc.req)
- s.Equal(wantErr, gotErr)
+ gotErr := s.service.Upload(tc.req)
+ s.Equal(wantErr, gotErr)
})
}
}
@@ -326,36 +326,36 @@
// Init ServiceSuite as above
-func (s *ServiceSuite) TestUpload() {
+func (s *ServiceSuite) TestUpload() {
// Init success request
req := Request{
// ...
}
// Init success action
- s.verifyService.MockVerify().Return(nil)
+ s.verifyService.MockVerify().Return(nil)
// ...
- gotErr := s.service.Upload(tc.req)
- s.NoError(gotErr)
+ gotErr := s.service.Upload(tc.req)
+ s.NoError(gotErr)
- s.Run("failed", func(){
+ s.Run("failed", func(){
// Alter failed request from default
req := Request{
// ...
}
- gotErr := s.service.Upload(tc.req)
- s.Error(gotErr)
+ gotErr := s.service.Upload(tc.req)
+ s.Error(gotErr)
})
- s.Run("another failed", func(){
+ s.Run("another failed", func(){
// Alter verify return
- s.verifyService.MockVerify().Return(someErr)
+ s.verifyService.MockVerify().Return(someErr)
- gotErr := s.service.Upload(tc.req)
- s.Error(gotErr)
+ gotErr := s.service.Upload(tc.req)
+ s.Error(gotErr)
})
// ...
diff --git a/docs/2023-06-10-incident-context.html b/docs/2023-06-10-incident-context.html
index 2332103..1b6afa3 100644
--- a/docs/2023-06-10-incident-context.html
+++ b/docs/2023-06-10-incident-context.html
@@ -81,12 +81,12 @@
My buggy code is like this:
- if err := doA(ctx); err != nil {
- log.Error(err)
+ if err := doA(ctx); err != nil {
+ log.Error(err)
// Skip error
}
-doB(ctx)
+doB(ctx)
The problem is doA
taking too long, so ctx
is
@@ -102,35 +102,35 @@
>):
- func main() {
- ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
- defer cancel()
+ func main() {
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
+ defer cancel()
- doA(ctx)
- doB(ctx)
+ doA(ctx)
+ doB(ctx)
}
-func doA(ctx context.Context) {
- ctx, ctxCancel := context.WithTimeout(ctx, 1*time.Second)
- defer ctxCancel()
+func doA(ctx context.Context) {
+ ctx, ctxCancel := context.WithTimeout(ctx, 1*time.Second)
+ defer ctxCancel()
select {
- case <-time.After(2 * time.Second):
- fmt.Println("doA")
- case <-ctx.Done():
- fmt.Println("doA", ctx.Err())
+ case <-time.After(2 * time.Second):
+ fmt.Println("doA")
+ case <-ctx.Done():
+ fmt.Println("doA", ctx.Err())
}
}
-func doB(ctx context.Context) {
- ctx, ctxCancel := context.WithTimeout(ctx, 3*time.Second)
- defer ctxCancel()
+func doB(ctx context.Context) {
+ ctx, ctxCancel := context.WithTimeout(ctx, 3*time.Second)
+ defer ctxCancel()
select {
- case <-time.After(2 * time.Second):
- fmt.Println("doB")
- case <-ctx.Done():
- fmt.Println("doB", ctx.Err())
+ case <-time.After(2 * time.Second):
+ fmt.Println("doB")
+ case <-ctx.Done():
+ fmt.Println("doB", ctx.Err())
}
}
@@ -185,9 +185,9 @@ doB context deadline exceeded
:
- func DisconnectContext(parent context.Context) context.Context {
+ func DisconnectContext(parent context.Context) context.Context {
if parent == nil {
- return context.Background()
+ return context.Background()
}
return disconnectedContext{
@@ -199,20 +199,20 @@ doB context deadline exceeded
parent context.Context
}
-func (ctx disconnectedContext) Deadline() (deadline time.Time, ok bool) {
+func (ctx disconnectedContext) Deadline() (deadline time.Time, ok bool) {
return
}
-func (ctx disconnectedContext) Done() <-chan struct{} {
+func (ctx disconnectedContext) Done() <-chan struct{} {
return nil
}
-func (ctx disconnectedContext) Err() error {
+func (ctx disconnectedContext) Err() error {
return nil
}
-func (ctx disconnectedContext) Value(key any) any {
- return ctx.parent.Value(key)
+func (ctx disconnectedContext) Value(key any) any {
+ return ctx.parent.Value(key)
}
@@ -223,34 +223,34 @@ doB context deadline exceeded):
- func main() {
- ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
- defer cancel()
- doA(ctx)
- doB(ctx)
+ func main() {
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
+ defer cancel()
+ doA(ctx)
+ doB(ctx)
}
-func doA(ctx context.Context) {
- ctx, ctxCancel := context.WithTimeout(ctx, 1*time.Second)
- defer ctxCancel()
+func doA(ctx context.Context) {
+ ctx, ctxCancel := context.WithTimeout(ctx, 1*time.Second)
+ defer ctxCancel()
select {
- case <-time.After(2 * time.Second):
- fmt.Println("doA")
- case <-ctx.Done():
- fmt.Println("doA", ctx.Err())
+ case <-time.After(2 * time.Second):
+ fmt.Println("doA")
+ case <-ctx.Done():
+ fmt.Println("doA", ctx.Err())
}
}
-func doB(ctx context.Context) {
- ctx, ctxCancel := context.WithTimeout(DisconnectContext(ctx), 3*time.Second)
- defer ctxCancel()
+func doB(ctx context.Context) {
+ ctx, ctxCancel := context.WithTimeout(DisconnectContext(ctx), 3*time.Second)
+ defer ctxCancel()
select {
- case <-time.After(2 * time.Second):
- fmt.Println("doB")
- case <-ctx.Done():
- fmt.Println("doB", ctx.Err())
+ case <-time.After(2 * time.Second):
+ fmt.Println("doB")
+ case <-ctx.Done():
+ fmt.Println("doB", ctx.Err())
}
}
diff --git a/docs/2023-07-01-pastebin.html b/docs/2023-07-01-pastebin.html
index 9183cc8..1bec43b 100644
--- a/docs/2023-07-01-pastebin.html
+++ b/docs/2023-07-01-pastebin.html
@@ -271,6 +271,11 @@ sudo pkill bluetoothd
+
+ Why always something is running at port 5000 on my mac
+
Firefox
diff --git a/docs/2023-08-23-real-world-crypto.html b/docs/2023-08-23-real-world-crypto.html
index 332198e..28c92df 100644
--- a/docs/2023-08-23-real-world-crypto.html
+++ b/docs/2023-08-23-real-world-crypto.html
@@ -132,7 +132,7 @@
Constant time comparison:
- for i := 0; i < len(x); i++ {
+ for i := 0; i < len(x); i++ {
// Use XOR instead of compare x[i] == y[i]
// If x[i] == y[i] -> XOR is 1
// Otherwise XOR is 0
diff --git a/posts/2022-07-31-sql.md b/posts/2022-07-31-sql.md
index 33472de..bfe501f 100644
--- a/posts/2022-07-31-sql.md
+++ b/posts/2022-07-31-sql.md
@@ -192,3 +192,4 @@ FROM information_schema.statistics;
- [Difference between text and varchar (character varying)](https://stackoverflow.com/a/4849030)
- [How to get the number of total results when there is LIMIT in query?](https://stackoverflow.com/q/33889922)
- [Run a query with a LIMIT/OFFSET and also get the total number of rows](https://stackoverflow.com/q/28888375)
+- [SQL best practices – don’t compare count(*) with 0](https://www.depesz.com/2024/12/01/sql-best-practices-dont-compare-count-with-0/)
diff --git a/posts/2023-07-01-pastebin.md b/posts/2023-07-01-pastebin.md
index 8fee2cc..f446e7b 100644
--- a/posts/2023-07-01-pastebin.md
+++ b/posts/2023-07-01-pastebin.md
@@ -136,6 +136,7 @@ Thanks:
- [Upgrading Homebrew and avoiding the failed to verify attestation error](https://til.simonwillison.net/homebrew/no-verify-attestations)
- [Use iMac M1 accent colours on any Mac](https://georgegarside.com/blog/macos/imac-m1-accent-colours-any-mac/)
- https://mahdi.jp/apps/accents
+- [Why always something is running at port 5000 on my mac](https://stackoverflow.com/q/72369320)
## Firefox