Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions spanner/spanner_snippets/snippet.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import (

"cloud.google.com/go/spanner"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"

"cloud.google.com/go/iam/apiv1/iampb"
database "cloud.google.com/go/spanner/admin/database/apiv1"
Expand Down Expand Up @@ -824,14 +827,25 @@ func run(ctx context.Context, w io.Writer, cmd string, db string, arg string) er
cfg := spanner.ClientConfig{
DatabaseRole: databaseRole,
}
opts := []option.ClientOption{}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In Go, it is more idiomatic to use var for an empty slice that will be appended to, rather than an empty slice literal. This avoids an unnecessary allocation and is generally preferred when the slice's initial capacity is not known.

Suggested change
opts := []option.ClientOption{}
var opts []option.ClientOption
References
  1. In Go, it is more idiomatic to use var for an empty slice that will be appended to, rather than an empty slice literal. (link)


adminClient, err := database.NewDatabaseAdminClient(ctx)
endpoint := os.Getenv("EXPERIMENTAL_HOST")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The environment variable name EXPERIMENTAL_HOST is quite generic. Consider using a more specific name like SPANNER_EXPERIMENTAL_HOST to avoid potential collisions with other tools or services that might use a similar naming convention.

if endpoint != "" {
opts = append(opts,
option.WithEndpoint(endpoint),
option.WithGRPCDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())),
option.WithoutAuthentication(),
)
cfg.IsExperimentalHost = true
}

adminClient, err := database.NewDatabaseAdminClient(ctx, opts...)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The run function returns an error, but errors during client creation are handled with log.Fatal, which terminates the process immediately. This prevents deferred functions (like adminClient.Close()) from running and is inconsistent with how other errors in this function are handled. Consider returning the error instead of using log.Fatal.

if err != nil {
log.Fatal(err)
}
defer adminClient.Close()

dataClient, err := spanner.NewClientWithConfig(ctx, db, cfg)
dataClient, err := spanner.NewClientWithConfig(ctx, db, cfg, opts...)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the adminClient creation, using log.Fatal here prevents the previously created adminClient from being closed via its deferred Close() call if spanner.NewClientWithConfig fails. It is better to return the error to the caller.

if err != nil {
log.Fatal(err)
}
Expand Down
Loading