Go関連のことを調べてみた2021年01月22日

Go関連のことを調べてみた2021年01月22日

golangでFargate運用を想定したDockerfile作成(Alpineベース)

# 概要
個人アプリにて、Fargateでのコンテナ運用を行うため、golang環境のDockerfileを作成しました。

当環境の特徴として、

– DockerイメージをAlpine Linuxベースを使用し、軽量化。
– マルチステージビルド機能を使用し、ビルド環境でgolangアプリやその他バイナリを作成し、軽量化。
– Fargateで運用するコンテナの中に入ってシェル操作するため、ssm-agentを導入。

です。

# 各種ファイル

### Dockerfile

~~~dockerfile
FROM golang:1.14.4-alpine3.12 as builder

ARG SSM_AGENT_VERSION=2.3.1205.0

RUN apk add –no-cache \
‘make~=4.3-r0’ \
‘git~=2.26.2-r0’ \
‘gcc~=9.3.0-r2’ \
‘libc-dev~=0.7.2-r3’ \
‘bash~=5.0.17-r0’

元記事を表示

GCPのSpannerで allow_commit_timestamp = true のフィールドに現在時刻を入れてはいけない

## はじめに

Spannerはスキーマに他のデータベース同様TIMESTAMP型がありますがオプションとして `allow_commit_timestamp = true` を指定でき、Spanner側の時計を基準としたタイムスタンプを打つことができます。

これによりアプリケーション側でセットした時刻に依存しない厳格な履歴を作成できますが使い方を間違えると書き込みに失敗するケースがあったので紹介します。

## TL;DR

* `allow_commit_timestamp = true` にしたフィールドに未来時刻を入れることはできない
* このフィールドにOSから取得した現在時刻を入れると時刻ブレで未来時刻になり書き込みに失敗することがある
* 代わりにプレースホルダーを使おう

## 検証

### 環境構築

以下のコマンドでSpannerを構築して下さい。gcloudの認証等は済んでいる前提でプロジェクト名は各々の環境に置き換えて下さい。

“`sql
— schema.sql として保存
CREATE TABLE users (
id STRING(MA

元記事を表示

Go言語でチャンネル書込がブロックされるのを無理矢理解決した話

# 概要

Go言語のチャンネルは非常に便利なんですが、正直複雑すぎてあまり使いこなせていません。

この記事は、**チャンネルの受信側のgoroutineが先に死んだ場合に、送信側のチャンネル書き込みが永久にブロックされるのを無理矢理解決**した事例です。

正直こんな書き方がGo言語的に良いのかどうかわからないので、ご意見等いただけると嬉しいです。

**バッドノウハウかもしれないのでご注意を!!**

## 参考

Go言語のチャンネル書き込みの時に…

| 条件 | 結果 |
|:—-:|:—-:|
| 受信ルーチンが生きていてチャンネルが満杯でない | ブロックしない |
| 受信ルーチンが生きていてチャンネルが満杯 | チャンネルが空くまでブロック |
| 受信ルーチンが死んでいる | 永久にブロック |
| チャンネルにnilが代入されている | 永久にブロック |
| チャンネルがcloseされている | panicする |

# panicするコード
[Playgroundへのリンク](https://play.golang.org/p/KwX4nRd

元記事を表示

sdk-goでdynamoDBの複雑なstructの値をupdateする

## やりたいこと
GoでのdynamoDBに対しての操作は割とめんどかったりします。単純なStringやIntのものであればまだ良いのですが、ListのMapのなかのListとか、値の構造が複雑になってくると気が滅入ります。

“`go
// シンプルなパターン
&dynamodb.UpdateItemInput{
TableName: aws.String(“sampleTable”),
Key: // 省略,
ExpressionAttributeValues: map[string]*dynamodb.Attribute{
“:ssv”: {
S: aws.String(“sampleStringValue”)
},
“:siv”: {
N: aws.String(strconv.Itoa(0)) // ここもintをstringに型変換してそれをaws.String()してkeyにはNを指定って感じでわかりづらい。
},
},
UpdateExpression: aws.String(“set samp

元記事を表示

RcppKagome – Rcpp経由でGoのライブラリを呼んで形態素解析するRパッケージ

[![paithiov909/RcppKagome – GitHub](https://gh-card.dev/repos/paithiov909/RcppKagome.svg)](https://github.com/paithiov909/RcppKagome)

## これは何?

Rで形態素解析するためのパッケージです。[Pure Goで辞書同梱な形態素解析器](https://qiita.com/ikawaha/items/ff27ac03e22b7f36811b)として知られる[ikawaha/kagome](https://github.com/ikawaha/kagome)をラップしています。

## 使い方

### インストール

ソースからビルドします。makeとGCCとGoが必要です。

“` r
remotes::install_github(“paithiov909/RcppKagome”)
“`

### 形態素解析

character vectorを渡せます。戻り値はリストです。

“`r
res <- RcppKagome::kagome("

元記事を表示

【自己学習用】はじめてのGo2

#基本的な文法の振り返り
####mainパッケージ
プログラムをコンパイルして実行すると,まずmainパッケージの中にあるmain()関数が実行される。

“`
package main

func main() {
}
“`

####インポート
インポートしたパッケージ内へは,パッケージ名にドットを付けてアクセスできる。

“`
package main

import (
“fmt”
“github.com/wdpress/gosample”
“strings”
)
func main() {
fmt.Println(“hello world”)
}
“`

####オプションの指定
任意の名前(上記ではf)を指定した場合はfで使用可能。
_を付けた場合は使用しないの意。
.を付けた場合は,使用時にパッケージ名が省略可能。

“`
package main

import (
f “fmt”
_ “github.com/wdpress/gosample”
. “strings”
)

func main() {

元記事を表示

Goの複数バージョン管理をanyenv+goenvで行う

Go言語で開発している際にローカルで複数バージョン使い分けしたい時がしばしば発生するので、その対策としてgoenvおよびanyenvを使ってバージョンの切り替えを容易にする方法を紹介します。

# goenvとは

https://github.com/syndbg/goenv

pyenvやrbenvをモデルに作られたGoのバージョン管理ツールです。
これを使うことによってバージョンの切り替え、Goの開発プロジェクトごとにバージョンを変更、環境変数でGoのバージョンの切り替えなどを行うことができるようになります。

# anyenvとは

https://github.com/anyenv/anyenv

〜env系のツールを管理するツールです。
上述のgoenvやpyenv,rbenvに加え、nodenvやtfenvなど様々な言語のバージョン管理ツールを制御することができます。
今回の記事ではGoだけを取り扱うのでanyenvはなくても大丈夫なのですが、今後他の言語のバージョン管理する可能性あることを考えて一緒に紹介しておきます。

# インストール

## anyenvのインスト

元記事を表示

Golangでのゼロ埋め

# Golangでのゼロ埋め
0~9の場合は数字の前に0を付け、
10以上の場合は0を付けない場合は以下の様に実現できる

“`
s := 3
str := fmt.Sprintf(“%02d”, s)
fmt.Println(str)
// 03

s2 := 13
str2 := fmt.Sprintf(“%02d”, s2)
fmt.Println(str2)
// 13
“`

知らずに以下の様な回りくどい方法で実現したので知ったときは衝撃だった…

“`
if num < 10 { ​ numStr = "0" + strconv.Itoa(num) ​ } else { ​ numStr = strconv.Itoa(num) ​ } ```

元記事を表示

Goでスライス内の最大値・最小値を抽出する関数

## はじめに
Goでコードを書いているとスライス内の最大値、もしくは最小値を算出する処理を
何度か利用したので忘れないためにもメモ

### スライス内の最大値を取得
“`
func maxInt(a []int) int {
sort.Sort(sort.IntSlice(a))
return a[len(a)-1]
}
“`

### スライス内の最小値を取得

“`
func minInt(a []int) int {
sort.Sort(sort.IntSlice(a))
return a[0]
}
“`

### サンプルコード

以下コードを[The Go Playground](https://play.golang.org/)でコピペして実行

“`
package main
import “fmt”
import “sort”

func main() {
test := []int{7, 8 ,1, 4, 3, 21}

fmt.Println(“max:”, maxInt(test))
fmt.Println(

元記事を表示

Go(Echo) Go Modules × Dockerで開発環境構築

# はじめに

フレームワークに`Echo`
ライブラリ管理に`go mod`
ホットリロードに`fresh`
を使用したGoの開発環境をDockerを使って構築したいと思います。
Goのバージョンは`Go 1.15`です。

この記事ではDockerのインストール方法や細かい解説等はしません。

# 最終的なディレクトリ構成
“`
.
├── app
│ ├── Dockerfile
│ ├── go.mod
│ ├── go.sum
│ └── main.go
└── docker-compose.yml
“`
[GitHub](https://github.com/suganuma3510/go-docker)
# 急いでいる人向け
[ここ](https://github.com/suganuma3510/go-docker)からコードをダウンロードして`docker-compose up`すればできます。

# Dockerfile作成

まず最初に適当なディレクトリを作成(私の場合go-dockerというディレクトリを作成)
上記のディレクトリ構成を参考

元記事を表示

go.modの補足 パッケージ

前回の続きです。

“`[go.mod]
module example.com

go 1.15

require github.com/labstack/echo/v4 v4.1.17
“`

上記のgo.modの一番上の
“`module example.com“`
の部分ですが、ここがimportして自分のパッケージを使う時の名前になります!
以下のような構成のプロジェクトの場合↓

test
 |–samplea–aaaaa.go
 |–sampleb–bbbbb.go
 |–main.go
 |–go.mod
 |–go.sum

“`[main.go]

package main

import(
“example.com/samplea”
“example.com/sampleb”
)
“`
このようにして使います。
ディレクトリの名前とモジュールの名前を同じにしたければ

“`[go.mod]
module

元記事を表示

Go + MySQL + nginxの開発環境をDocker(docker-compose)で作る

# やりたいこと

– Go、MySQL、nginxの開発環境をDocker(docker-compose)で作る
– Goの外部パッケージはGo Modulesで管理
– Goのプロジェクトを実践的なものにする
– DBのテーブル管理はマイグレーションを使う
– testはテスト用のDBを使う

# こんな人におすすめ

– GoとMySQLでAPIサーバーの開発がしたい
– 環境構築はDockerで手っ取り早く済ませたい
– 拡張しやすいGoのプロジェクトが欲しい

# 使用するフレームワーク、バージョン

| | バージョン |
| —- | —- |
| Go | 1.15 |
| MySQL | 5.7 |
| nginx | 1.19 |

Goのフレームワークは[Gin](https://github.com/gin-gonic/gin)、ORMに[GORM](https://gorm.io/docs/)を使用。

# ディレクトリ構成

“`
├── docker-compose.yml
├── Dockerfile
├── ap

元記事を表示

Slack ソケットモードの最も簡単な始め方 (Go 編)

### slack-go/slack がソケットモードに対応 :tada:

広く使われている Go SDK の [github.com/slack-go/slack](https://github.com/slack-go/slack
) がソケットモード対応しました :tada: @mumoshu さんと @kanata2 さんの素晴らしい仕事です :clap:

https://github.com/slack-go/slack

### ソケットモードアプリ起動までの手順

この記事では、[Slack ソケットモードの最も簡単な始め方](https://qiita.com/seratch/items/1a460c08c3e245b56441)で使ったサンプルアプリと同じものを、この Go SDK を使って動かす方法を解説します。

#### プロジェクトをつくる

ここで紹介するサンプルは v0.8.0 以上で動作します。

“`
go mod init socket-mode-app
go get github.com/slack-go/slack@v0.8.0
“`

元記事を表示

GoのHTTP実装を読んだ知見をまとめる~FIFOを5通りで実装する~

# はじめに
引き続き、GoのHTTP実装と絡めて書く。今日はFIFO実装について。
経緯は[こちら](https://qiita.com/behiron/items/78d023be96058224e583#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)

[Russ CoxによるHTTPクライアントのFIFO実装](https://github.com/golang/go/blob/682a1d2176b02337460aeede0ff9e49429525195/src/net/http/transport.go#L1242-L1306)が工夫されていて非常に興味深かった。
コメントを見ると、[Okasaki’s purely functional queue](https://www.amazon.co.jp/-/en/Chris-Okasaki/dp/0521631246)を元に、少し工夫したものらしい。

今回はそれらに触れた上でGoでFIFOを5通りの方法で実装していきたいと思う。

実装およびテストコードは[GitHub](https://gi

元記事を表示

Goでテストを書くために、まずinterfaceを設計するということ

## Goでテストコードを書くことになった場合に

あなたが、勤務先で上長から「テストコードを書いてください」と指示されたとき、
テストが書ける設計になっているでしょうか。

この記事では、**S3からファイルを取得して読み取る**というユースケースに対して
テストを書くことについて考えていきます。

## テストが書きづらいケース

“`main.go
var awssess = newSession()
var s3Client = newS3Client()

const defaultRegion = “ap-northeast-1”

func newSession() *session.Session {
return session.Must(session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
}))
}

func newS3Client() *s3.S3 {
return s3.New(awssess, &aws.Conf

元記事を表示

【Go】go-oidcを使ってOpen ID Connectを利用する

## Open ID Connect
– outh2の進化版でトークン発行の処理がある
– アプリケーション自体にユーザーパスワードなどの認証情報を持たせずに、別のプロバイダー(ここではGoogle)に委任する
– プロバイダーはいろいろある
– Google
– AzureAD
– AWS Cognito
– outh0
– `state`という概念があり、クロスサイトスクリプティングなどのなりすましを防止

## 公式パッケージ
https://github.com/coreos/go-oidc

## インストール

“`bash
git cloen https://github.com/coreos/go-oidc
“`

## exampleのREADMEの通りにセットアップする

“`
cd go-oidc/example
“`

“`
yuta:~/go-oidc/example (v3=) $ cat README.md
# Examples

These are example uses of the oidc packag

元記事を表示

【Golang】サポートする GOOS と GOARCH を一覧で確認するコマンド(ビルドの対応プラットフォーム確認)

> `go build` する際に指定可能な `$GOOS` と `$GOARCH` の一覧を**コマンドで確認**したい。

なんか、Go 言語のバージョンだけでなく環境によってもビルドできる(サポートされた)OS やアーキテクチャが異なるようだったので、シェル・スクリプトで事前にチェックしたいのです。

[「golang GOOS 一覧 確認 コマンド」でググって](https://www.google.com/search?q=golang+GOOS+%E4%B8%80%E8%A6%A7+%E7%A2%BA%E8%AA%8D+%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89)もピンポイントな記事が出てこなかったので、自分のググラビリティとして。

## TL; DR

> `go tool dist list`

## TS; DR

“`shell-session
$ go tool dist list
aix/ppc64
android/386
android/amd64
android/arm
…(以下省略)

$ go version
go

元記事を表示

Macでgqlgenのserver.goを起動するとファイアウォール警告が出る

GoのGraphQLサーバライブラリであるgqlgenの開発サーバ(GraphQL Playground)をMac上で起動すると、ファイアウォールの警告が出てしまってめんどくさい。
![20210108160313.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9148/5e192904-6f03-13d6-85c8-5c0daf851b80.png)

通常はMacの環境設定のセキュリティとプライバシーのファイアウォール設定で例外を設定するのですが、うまくいかなかったので別の方法で解決します。

server.goの最後で次のようになっています。

“`go
log.Fatal(http.ListenAndServe(“:”+port, nil))
“`

これだと「0.0.0.0」でlistenするようです。0.0.0.0はすべてのネットワークインタフェースを指し、過剰です。

以下のように「localhost」まはは「127.0.0.1」を明示するように変更します。

“`go
log.Fa

元記事を表示

LINE Bot からDropboxに写真をアップロードする

タイトルの通り、LINE Bot からDropboxに写真をアップロードするシステムを作ってみました。現状は課題だらけですが、主要機能が実装できたので投稿します。

LINE Botに画像を送ると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951392/9964bfae-caa5-bcb8-6cda-0e575d2335c7.png)

Dropboxにアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951392/215a2172-9836-91d7-5724-dac47a84a336.png)

ソースコード

“`go:main.go
package main

import (
“io”
“log”
“net/http”
“os”

“github.com/dropbox/dropbox-sdk-go-unofficial/dr

元記事を表示

go moduleを使う

## 環境変数で有効化する
“`
go env -w GO111MODULE=on
go env | grep MOD
“`

## 初期化処理

“`
go mod init test
“`

go.modが作成されている

“`go.mod
module test

go 1.13
“`

## 起動
自動的にgo getされていないパッケージがインポートされる

“`
go run main.go
“`

元記事を表示

OTHERカテゴリの最新記事