0
0

More than 3 years have passed since last update.

zmq4でFizzBuzzする

Last updated at Posted at 2020-03-14

初めに

Goのすごい人がついったーでgophernotes の pure go zeromq 対応が入った。とツイートしてた。
すごい人が言ってるんだから使っておいて損無いハズ。

5分ぐらい考えた結果、FizzBuzzすることに決めた。
プログラマならFizzBuzzとか数列とか使いたくなるんだからしょうがない。

できたもの

dekita.png

斬新なFizzBuzz結果

zeromqとは

ブローカーなしのメッセージング。ブローカー不要が何より嬉しい。
どうせ通信相手そんなにいないのに、いちいちサーバ立てたくない。
詳しくはZeroMQ参照。

FizzBuzzとは

よくやる奴。割愛。

【非検証】gophernotesを使おうとしたけど使えなかったので手順だけまとめる

gophernotesとは、Jupyter NotebookのGo言語版的な奴。詳しくはgophernotesを参照。

諸般の事情(Windowsしか持ってない)があるので、Dockerを利用する必要がある。
が、今現在Dockerが利用できる端末がない。
なので環境構築の順番だけでもまとめる。

簡単に利用するためにgopherdata/gophernotesをベースとして自分の使いやすいイメージを作る。

Dockerfile
FROM gopherdata/gophernotes:latest

RUN go get github.com/go-zeromq/zmq4 \
  && mkdir -p /etc/jupyter

COPY ./entrypoint.sh /entrypoint.sh
COPY ./jupyter_notebook_config.py /etc/jupyter/jupyter_notebook_config.py

ENTRYPOINT [ "/entrypoint.sh" ]

entrypoint.sh
jupyter notebook --no-browser --allow-root --ip=0.0.0.0  --config=/etc/jupyter/jupyter_notebook_config.py

configはgopherdata/gophernotesのイメージをいったん走らせてから、コンテナに吐いてもらう。

# コンテナ走らせて中に入る
docker run -it -d gopherdata/gophernotes
docker exec -it ${gophernotesのid} /bin/sh
# config吐く
jupyter noteboopk --generate-config
mv /path/to/jupyter_notebook_config.py /tmp/
exit
# ローカルに落とす
docker cp ${gophernotesのid}:/tmp/jupyter_notebook_config.py ./

手元で試すだけなら、jupyter_notebook_config.pyのtokenを書き変える。
後はコンテナをビルドして実行するだけ

docker build -t miyatamagophernotes:1.0.0 .
docker run -it -p 8888:8888 miyatamagophernotes:1.0.0

zmq4

まずはpub側から

publish側

1秒おきに100までのFizzBuzzを垂れ流す。

package main

import (
    "fmt"
    "time"
    "context"
    "sync"
    "github.com/go-zeromq/zmq4"
)

func main() {
    err := startPublisher()
    if err != nil {
        fmt.Printf("%v", err)
    }
}

func startPublisher() error {
    pub := zmq4.NewPub(context.Background())
    defer pub.Close()

    err := pub.Listen("tcp://*:5563")
    if err != nil {
        return err
    }
    for {
        publishFizzBuzz(pub)
        if err != nil {
            return err
        }
        time.Sleep(time.Second)
    }
    return nil
}

func publishFizzBuzz(publisher zmq4.Socket) {
    getFizzBuzzText := func(num int) string {
        if (num % 15) == 0  {
            return "FizzBuzz"
        }
        if (num % 3) == 0 {
            return "Fizz"
        }
        if (num % 5) == 0 {
            return "Buzz"
        }
        return fmt.Sprintf("%d", num)
    }

    wg := &sync.WaitGroup{}
    for i := 0; i < 100 ; i++ {
        wg.Add(1)
        go func(number int) {
            defer wg.Done()
            msg := zmq4.NewMsgFrom(
                []byte("FizzBuzz"),
                []byte(getFizzBuzzText(number)),
            )
            publisher.Send(msg)
        }(i + 1)
    }
    wg.Wait()
}

続いてsub

Subscribe側

受け取って表示するだけ

package main

import (
    "context"
    "fmt"
    "github.com/go-zeromq/zmq4"
)

func main() {

    err := startSubscribe()
    if err != nil {
        fmt.Printf("%v", err)
    }
}

func startSubscribe() error {
    sub := zmq4.NewSub(context.Background())
    defer sub.Close()

    err := sub.Dial("tcp://localhost:5563")
    if err != nil {
        return err
    }

    err = sub.SetOption(zmq4.OptionSubscribe, "FizzBuzz")
    if err != nil {
        return err
    }

    for {
        msg, err := sub.Recv()
        if err != nil {
            return err
        }
        fmt.Printf("%s\n", msg.Frames[1])
    }
}

ふりかえり

今回も様々な知見を得られた

  • FizzBuzzをgophernotes上のZeroMQでやる必要は全くない
  • gophernotesが利用できなかったので単純にzmq4でFizzBuzzしただけになった
  • 並列処理したおかげでFizzBuzzの結果が正しいかよく分からなくなった
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0