たなしょのメモ

日々勉強していることをつらつらと

週報8/17

先週は忙しくて週報を休んでしまった。反省せねば。

Go

hmac

APIkeyの認証やDBのパスワードとの関係を確認する際に使うらしい。

package main

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
    "fmt"
)

var DB = map[string]string{
    "User1Key": "User1Secret",
    "User2Key": "User2Secret",
}

func Server(apiKey, sign string, data []byte) {
    apiSecret := DB[apiKey]
    h := hmac.New(sha256.New, []byte(apiSecret))
    h.Write(data)
    expectedHMAC := hex.EncodeToString(h.Sum(nil))
    fmt.Println(sign == expectedHMAC)
}

func main() {
    const apiKey = "User1Key"
    const apiSecret = "User1Secret"

    data := []byte("data")
    h := hmac.New(sha256.New, []byte(apiSecret))
    h.Write(data)
    sign := hex.EncodeToString(h.Sum(nil))

    fmt.Println(sign)

    Server(apiKey, sign, data)
}

semaphore

goruotineの処理を待ったり、複数あるgoruoutineを一つだけ起動するようにしたりできるようになるらしい。
あまり良くわかっていない。

package main

import (
    "context"
    "fmt"
    "golang.org/x/sync/semaphore"
    "time"
)

var s *semaphore.Weighted = semaphore.NewWeighted(1)

func longProcess(ctx context.Context) {
    isAcquire := s.TryAcquire(1)
    if !isAcquire {
        fmt.Println("Could not get lock")
        return
    }
    //if err := s.Acquire(ctx, 1); err != nil {
    // fmt.Println(err)
    // return
    //}
    defer s.Release(1)
    fmt.Println("Wait...")
    time.Sleep(1 * time.Second)
    fmt.Println("Done")
}

func main() {
    ctx := context.TODO()
    go longProcess(ctx)
    go longProcess(ctx)
    go longProcess(ctx)
    time.Sleep(2 * time.Second)
    go longProcess(ctx)
    time.Sleep(5 * time.Second)
}

ini

iniファイルを読み込む際に使用する。
DB等のアクセスに便利そう。

package main

import (
    "fmt"
    "gopkg.in/ini.v1"
)

type ConfigList struct {
    Port      int
    DbName    string
    SQLDriver string
}

var Config ConfigList

func init() {
    cfg, _ := ini.Load("config.ini")
    Config = ConfigList{
        Port:      cfg.Section("web").Key("port").MustInt(),
        DbName:    cfg.Section("db").Key("name").MustString("example,sql"),
        SQLDriver: cfg.Section("db").Key("driver").String(),
    }
}

func main() {
    fmt.Printf("%T %v\n", Config.Port, Config.Port)
    fmt.Printf("%T %v\n", Config.DbName, Config.DbName)
    fmt.Printf("%T %v\n", Config.SQLDriver, Config.SQLDriver)
}

websocket

websocketを利用するとjson形式でデータをひっぱてくれる。

package main

import (
    "log"
    "net/url"

    "github.com/gorilla/websocket"
)

type JsonRPC2 struct {
    Version string      `json:"jsonrpc"`
    Method  string      `json:"method"`
    Params  interface{} `json:"params"`
    Result  interface{} `json:"result,omitempty"`
    Id      *int        `json:"id,omitempty"`
}
type SubscribeParams struct {
    Channel string `json:"channel"`
}

func main() {
    u := url.URL{Scheme: "wss", Host: "ws.lightstream.bitflyer.com", Path: "/json-rpc"}
    log.Printf("connecting to %s", u.String())

    c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
    if err != nil {
        log.Fatal("dial:", err)
    }
    defer c.Close()

    if err := c.WriteJSON(&JsonRPC2{Version: "2.0", Method: "subscribe", Params: &SubscribeParams{"lightning_ticker_BTC_JPY"}}); err != nil {
        log.Fatal("subscribe:", err)
        return
    }

    for {
        message := new(JsonRPC2)
        if err := c.ReadJSON(message); err != nil {
            log.Println("read:", err)
            return
        }

        if message.Method == "channelMessage" {
            log.Println(message.Params)
        }
    }
}

エミュレーター作成

先週あたりからエミュレーターの作成をはじめた。 進捗は別途上げるかもしれませんが一応作りかけをリンクしておく。 https://github.com/jacoloves/emulater_book_pra/commit/c29e57a4b2977fa88a5de949110390df7d733220#diff-25d902c24283ab8cfbac54dfa101ad31

読書

https://note.com/shosagyo/n/nd0ded152eb37

https://note.com/shosagyo/n/n119ba3f125ee