- 1. emacs+eglotでgoplsのロードが重い問題に対処した
- 2. Goでtemplateをキャッシュする
- 3. Go!!
- 4. Go/gRPCコード生成の変更について
- 5. Goのリリースアセットの配置を自動化したい
- 6. [Go] slack-go/slackによるメッセージ一括削除
- 7. Go(Gorm)+MySQLなDocker環境でdial tcp connection refusedが発生した際の対処法
- 8. goroutineでバックグランドタスク実行する例
- 9. パッケージ名を指定してgo buildしよう
- 10. 自作アプリケーションのデプロイに役立つなにか
- 11. Golangに入門してみた: Exercise: Loops and Functions
- 12. Go言語のGUIライブラリfyneでハマったことメモ
- 13. [Go]Go製APIサーバで認証処理を作成する
- 14. 青いベンチ診断の結果をひたすらtwitterに投稿するアカウントをつくった
- 15. React+axiosでPOST送信したデータをGoで受け取る
- 16. Goroutineとselectとchannelを使って共同作業
- 17. SAMとGoのテンプレートエンジンでSSR
- 18. goroutineチートシート
- 19. “テストカバレッジ強制ギプス” 導入
- 20. 【Go】学習メモ② ~Goroutine, Channel~
emacs+eglotでgoplsのロードが重い問題に対処した
単純なのだが、引っかかったためメモとして残す
# 1. 問題
– emacsでLanguage Server Protocolクライアントであるeglotを使用し、Go言語のserverとしてgoplsを使用した
– 設定した状態のemacsで`.go`ファイルを開くと、ものすごく重い以下のようなエラーがでてくる
“`
Error in menu-bar-update-hook (imenu-update-menubar): (jsonrpc-error “request id=2 failed:” (jsonrpc-error-message . “Timed out”))
“`# 2. 原因
eglotがプロジェクトルートを正しく探すことができていなかった。今回の場合はこのようなメッセージがでていた。“`
[eglot] Connected! Server `gopls’ now managing `go-mode’ buffers in project `~’.
“`ホームフォルダ直下を全て探しにいっていたため、時間がかかっていた。
# 3. 解
Goでtemplateをキャッシュする
Golangのtemplateをキャッシュする方法を学んだのでメモ
“`golang:template.go
func CreateTemplateCache() (map[string]*template.Template, error) {
myCache := map[string]*template.Template{} //htmlの連想配列を作成pages, err := filepath.Glob(“./templates/pages/*.html”) // ./templates/pages/にあるhtmlファイルのpath全てを取得し、配列に格納
if err != nil {
return myCache, err
}
for _, page := range pages {
name := filepath.Base(page) // ファイル名を取得
ts := template.Must(template.New(name).ParseFiles(page)) //newで新しいテンプレートを作成し、ParseFi
Go!!
https://github.com/noydmt/hello_go
Go/gRPCコード生成の変更について
結構時間が経っているのですが、Go/gRPCでのサーバー開発において、2020年にコード生成の方法が変更されました。
最近gRPCを利用し始めた方は特に気にされる必要はありませんが、以前からGoでgRPCサーバーを構築していて
生成プラグインを入れ替えてないけどそろそろ更新しとくかーといった際に役立ちそうな情報として記事にしておきます。## 以前の生成方法
GoでgRPCサーバーのコード生成をする際、
元はprotocプラグインとして[golang/protobuf](https://github.com/golang/protobuf)を使用していました。この際にはこのようなコマンドでコード生成を行なっていました。
“`bash
$ protoc -I . \
–go_out=plugins=grpc:.
–go_opt=paths=source_relative \
./helloworld.proto
“`このコードから生成される`
.pb.go`に必要な全てのコードが入っていました。 ## protocプラグイ
Goのリリースアセットの配置を自動化したい
# これを自動化したい
GitHubのReleaseにクロスコンパイルで作成したアーカイブを配置(Assets)
こんなかんじ
> ![スクリーンショット 2021-12-30 19.43.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/908316/0002d5a2-dfb0-c2dd-6ea5-36dc424eab2b.png)
> [Prometheus](https://github.com/prometheus/prometheus/releases)# 方法
GitHub ActionsのパイプラインでOS・CPUアーキテクチャごとのアーカイブを作成し、リリースに配置します。
GitHub Actionsにアーカイブを作成するコマンドを書いてもいいのですが、自分はMakefileで書いてみました。
(GitLabを使うことが多いのでそちらに流用できるように)– [./Makefile](#Makefile)
– [./.github/workflow/release.y
[Go] slack-go/slackによるメッセージ一括削除
普段からGoogle CalendarとSlackを連携して使っていて、新規予定作成時にSlack通知がくるように設定しています。ところが、この通知が溜まってくると全体のメッセージ数を圧迫してきます。
そこでSlackAPIを用いて、指定したチャンネル・タイトルの投稿を一括削除することにしました。折角なので、楽にPythonではなく、勉強がてらGoを用いて実行してみることに。Slack APIの仕様変更もあり、あまり情報がなかったので、まとめてみました。
# 0.環境
– Go: 1.16.3
– slack-go/slack: 0.10.1# 1.APIトークンの取得
以前使われていたトークンは「レガシートークン」と呼ばれているようです。新しいトークンはアプリを作成した上で、必要な権限を設定する必要があります。[^1][^1]: 参考: https://risaki-masa.com/how-to-get-api-token-in-slack/
今回は、このように設定しました。
Go(Gorm)+MySQLなDocker環境でdial tcp connection refusedが発生した際の対処法## エラー内容
`docker-compose up`時に以下のエラーが発生しました。
“`terminal
[error] failed to initialize database, got error dial tcp 172.19.0.2:3306: connect: connection refused
“`## 原因
docker-composeで`container_name`を指定していなかったため## 対処法
### Before
docker-compose.yml
“`yml
version: “3.9”
services:
backend:
build: .
ports:
– 8000:8000
volumes:
– .:/app
depends_on:
– dbdb:
image: mysql:5.7.22
restart: always
environment:
MYSQL_DATABASE: ambassador
goroutineでバックグランドタスク実行する例
####背景####
以下のことをgoroutineで実現したいです。つまり、メインスレッドでFibonacci計算ではなく、goroutineでバックグランド計算したいです。![スクリーンショット 2021-12-30 14.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/fa722258-c61d-18c0-2647-cc4d4a6c460f.png)
####例1####
“`golang
func main() {
endChannel := make(chan int)
go backgroundTask(endChannel)
<- endChannel // main goroutineを終了させるまで、endChannelの補填を待ち } func backgroundTask(endChannel chan int) { fmt.Println("background running...") fmt.Println("result:
パッケージ名を指定してgo buildしよう
## はじめに
[フューチャー Advent Calendar 2021](https://qiita.com/advent-calendar/2021/future)の7日目です。
本記事では `go build main.go` と `go build {パッケージ名}` としてビルドしたときの微妙な違いについて説明します。Goのバージョンは `go1.18beta1` で確認しています。
Go 1.18から `runtime/debug` パッケージの `ReadBuildInfo()` を使って、ビルドしたときのVCSのハッシュを取得できるようになりますが、このビルドしたときの微妙な違いが影響するようになります。[^1]
https://tip.golang.org/doc/go1.18#go-command[^1]: `go version -m` でも確認できます。https://pkg.go.dev/cmd/go#hdr-Print_Go_version
## `go build` の引数による違い
`go build` でGoのソースをビルドして、実行バイ
自作アプリケーションのデプロイに役立つなにか
「`docker-compose`で開発して結局本番環境なし」みたいなことが続いたので流石にそれは卒業しようと思い、作って書いてみました。
モバイル系はあんまり参考にならないと思います。# 目標
– 開発環境どまりをやめる
# 基礎の基礎
## 自作アプリケーションを動かすには
– (ビルド)
– インストール
– 実行に必要なファイルの配置(assets等)をする必要がある。
※ ビルド不要な場合はインストール(配置)のみ
## よくあるパターン
[tingtt/prometheus_sh_exporter](https://github.com/tingtt/prometheus_sh_exporter)
自分のリポジトリだけど、よく見るパターンを真似して作ってみました。注目ポイントは[リリース](https://github.com/tingtt/prometheus_sh_exporter/releases)のページと[Makefile](https://github.com/tingtt/prometheus_sh_exporter/blo
Golangに入門してみた: Exercise: Loops and Functions
# Golangに入門してみた: Exercise: Loops and Functions
最近、転職活動をしているときにgRPCについての話があり、あまり詳しく知らなかったのでハンズオンしたいな、と思いどうせならgRPCの醍醐味である別言語間での通信を実現してみたいなと思い、現在使えるJavaScript, Python, Rubyに加え、流行のGolangを用いてAPI作ってみたいなと思い、Glangのtutorialをやってみました。
そこで、とりあえずGolangのfor文 + if文を使って平方根を求めるエクササイズがあったので、それをググりながら書いてみた。そこまで難しくないし、ヒントも出されているので、5分くらいで終わったのですが、その回答を載せます。答えは見てないので、非効率なプログラム書いているかもしれませんが、まぁいいでしょう。
## エクササイズ内容
こちらのページのエクササイズを行いました。
https://go-tour-jp.appspot.com/flowcontrol/8![](https://storage.googleapis.com/
Go言語のGUIライブラリfyneでハマったことメモ
# 概要
Go言語のGUIライブラリである[fyne](https://github.com/fyne-io/fyne)を使っていて、いくらか戸惑う場面が多かったので、対処法をここにメモしておきます。# ハマったこととその対処法
## ボタンの色の変更
fyneのライブラリには、ウィジェットとして[button](https://developer.fyne.io/widget/button)が用意されています。
この`button`ウィジェットは、ライブラリのソースコードを見ればわかる通り、見た目に関する情報はあまり持っていないようです。https://github.com/fyne-io/fyne/blob/master/widget/button.go
“`go:button.go
type Button struct {
DisableableWidget
Text string
Icon fyne.Resource
// Specify how prominent the button should be, High will highlight the
[Go]Go製APIサーバで認証処理を作成する
## はじめに
Go、Ginを使って認証処理を実装していきます
認証情報はCookieを使ってセッションに保持します## 環境
Golang 1.16.4
Gin 1.7.4## リクエスト用のモデルを作成します
メールアドレスとパスワードで認証していきます“`login.go
type Login struct {
Email string `json:”email” bson:”email”`
Password string `json:”password” bson:”password”`
UpdatedAt time.Time `json:”updated_at”`
CreatedAt time.Time `json:”created_at”`
}
“`## ログイン用のhandler
“`login_handler.go
type LoginHandler interface {
Login(ctx *gin.Context)
}type loginHandler struct {
loginUsecase log
青いベンチ診断の結果をひたすらtwitterに投稿するアカウントをつくった
[Zenn](https://zenn.dev/okaponta/articles/d89b8c99458b22)にも投稿したので、好きな方でお読みいただければと思います。
# はじめに
みなさま「青いベンチ」という曲はご存知でしょうか。
「この声が枯れるくらいに 君を好きと言えばよかった」からはじまるサビは聞いてて心地いいですね。さて、私がこの曲を知ったのは[青いベンチ診断](https://shindanmaker.com/240064)というものです。
これがまた面白くて、1/157464の確率で「青いベンチ/サスケ」という文字列が揃うものになります。
確率からしてだいたい外れるんですが、以下のような診断結果が出力されてクスってきてしまいます。サスチン青ベチ/ベンチ#shindanmakerhttps://t.co/X1WXZqTFWF
— Kohei Okamoto (@okaponta_) December 28, 2021
揃わなかった文字列を言い合うみたいなtogetterもありました。
https://togetter.com/li/452165
2021年の終わりになぜか「ひたすらこの診断結果を投稿するBotを作りたい」と強く
React+axiosでPOST送信したデータをGoで受け取る
JSON形式かx-www-form-urlencoded形式かで、実装方法が異なるみたいです。
## バージョン
axios 0.24.0
go 1.16.6
react ^17.0.2## それぞれの違い
### x-www-form-urlencoded形式
Content-Type ・・・ application/x-www-form-urlencoded
例 ・・・ a=1&b=1(エンコード後:%20a%3D1%26b%3D1)
Go(サーバー側)の実装の際にr.Form.Get(“name”)、r.FormValue(“name”)、r.PostFormValue(“name”)のメソッドで送信されたデータを取り出せる。multipart/form-data形式もGoの実装方法は同じだが、key-value型のデータを送るのでapplication/x-www-form-urlencoded形式を使うことにする。### JSON形式
Content-Type ・・・ application/json
例 ・・・ {“a”:1,”b”:2}
Go(サーバー側)の実装
Goroutineとselectとchannelを使って共同作業
田中君:1作業あたり1秒
鈴木君:1作業あたり1秒ルール
– 作業6個分になったら仕事終了
– 仕事が終了するまでにかかった時間を計測する田中君だけで作業をした場合 (鈴木君のgoroutineをコメントアウト)
“`go
package main
import (
“fmt”
“time”
)var total_work = []string{}
func tanaka(ch chan string) {
for {
time.Sleep(1 * time.Second)
ch <- "作業" } } func suzuki(ch chan string) { for { time.Sleep(1 * time.Second) ch <- "作業" } } func main() { start_time := time.Now() c1 := make(chan string) c2 := make(chan string) go tanaka(c1) // go suzuki(c2) for { fmt.Pr
SAMとGoのテンプレートエンジンでSSR
静的なテンプレートを読み込んでSSRを行うWebアプリケーションを作成します。
## 前提知識
* AWS SAM と Golang を利用して Severless なWebアプリケーションを作成することができる。
* Golang の html/template パッケージを利用してHTML形式の文字列を標準出力することができる。(以後AWSとlangは省略して記述します)
## Lambdaで静的なファイルを扱う
様々な方法があるかもしれませんが、今回は `AWS Lambda Layer`[^1] を利用します。
この機能を利用することで、 HTMLやCSS等の静的なデータをLambdaのzipファイルに含めることができます。SAMでは、SAMのテンプレートファイル内に設定を記述することでLambda Layerを構築することができます[^2]。
## 構築
早速SAMでLambda Layerを利用したアプリケーションを構築してみましょう。
今回は以下のような単純なページを作成していきます。# 概要
goroutineはGo言語において花形とも言える機能ですが、
実際に動くものを作ろうとなると落とし穴も多く非常に難しいです。これは防備録を兼ねたチートシートです。
そのままコピペして`go run`すれば動くと思います。
随時書き足していきますこのドキュメントで使用しているコードはgitHubにまとめてあります
https://github.com/nc30/golang_examples/tree/main/goroutine## 基本形
basic.go
https://github.com/nc30/golang_examples/blob/main/goroutine/basic.go
“`go
package mainimport (
“log”
“time”
)// goroutineはpythonで言うthureadingのようにfunction単位で並列処理を行う
// go言語の花形とも言えるもので、多言語よりも簡単で安全に行うことができる
// 今回は一次関数として渡しているが、もちろん関数を渡すことでも動かすことがで
“テストカバレッジ強制ギプス” 導入
## テストカバレッジ強制ギプスとは
* テストカバレッジが**基準値以下ならマージをできなくしてしまう**機構のこと (をこの記事で勝手にそう呼んでいます)
* この記事では、**Go のプロジェクト**を運用されている方を対象に**テストカバレッジ強制ギプス**を**15分**で導入できるように紹介します
* 具体的には、CI でテストカバレッジを計測して、[基準値以下なら fail](https://github.com/nrnrk/gotestcoveragecheck/pull/1) にさせるようにします
* テストカバレッジ強制ギプスを導入して、単体テストを充実させ快適な開発ライフを楽しみましょう![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150399/f6763328-6da4-ad39-164e-35a20f94b422.png)
## 背景
私のチームでは、 Go を用いたバックエンドサービスの開発をしています。開発の中でいくつか気になることが出て
【Go】学習メモ② ~Goroutine, Channel~
#はじめに
前回の学習メモの続きです。
GoroutineとChannelについてまとめました。https://qiita.com/suzuki0430/items/6674ffa239dc539e0fd7
#シリアル処理
本題の前に、シリアル処理についてまとめます。
まずは以下のように、5つのリンクにhttpリクエストが正常に送られるかどうかをチェックするコードを考えます。“`go:main.go
func main() {
links := []string {
“http://google.com”,
“http://facebook.com”,
“http://stackoverflow.com”,
“http://golang.org”,
“http://amazon.com”,
}for _, link := range links {
checkLink(link)
}
}func checkLink(link string) {
_, err := http.Get(link)
if err != nil {