2020/08,江端さんの技術メモ

$ pacman -Su
エラー: mingw32: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" は不明です
エラー: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" をリモートで検索できませんでした
エラー: mingw64: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" は不明です
エラー: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" をリモートで検索できませんでした
エラー: msys: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" は不明です
エラー: キー "4A6129F4E4B84AE46ED7F635628F528CF3053E04" をリモートで検索できませんでした
エラー: データベース 'mingw32' は無効です (無効または破損したデータベース (PGP 鍵))
エラー: データベース 'mingw64' は無効です (無効または破損したデータベース (PGP 鍵))
エラー: データベース 'msys' は無効です (無効または破損したデータベース (PGP 鍵))

てな感じのことが続き、

$pacman -S tree // treeのインストール

すら、できない有様。

で、1時間くらい回遊し続けて、この記事「MSYS2でPGP鍵が不明とか」の内容を試してみました。

$ wget http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz
$ wget http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig
$ pacman-key --verify msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz{.sig,}
$ pacman -U --config <(echo) msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz
$ pacman -U msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz

インストールするか? の問いには、"Y(es)"を連打していました。

全く理由は分かりませんが、PGP鍵の交換はできたようで、"tree"のインストールできました。

2020/08,江端さんの技術メモ

Dockerコンテナのサーバ化には、目処がついたので、今度はクライアント化の方を検討中です。

まずは、mkdir ~/go_echo/client を作って、そこにclient.goを放り込みました。

現時点での、Dockerfileは以下です。

# ベースとなるDockerイメージ指定
FROM golang:latest
# コンテナ内に作業ディレクトリを作成
RUN mkdir /go/src/client
# コンテナログイン時のディレクトリ指定
WORKDIR /go/src/client
# ホストのファイルをコンテナの作業ディレクトリに移行
ADD . /go/src/client

# gorillaのパッケージを入れる
RUN go get github.com/gorilla/websocket

現時点での、docker-compose.ymlは以下です。

version: '3' # composeファイルのバーション指定
services:
  client: # service名
    build: . # ビルドに使用するDockerfileがあるディレクトリ指定
    tty: true # コンテナの起動永続化

    volumes:
      - .:/go/src/client # マウントディレクトリ指定
    #ports:
    #   - "8080:8080"
    #expose:
    #   - "8080"

で、$ docker-compose build
$ docker-compose up -d
$ (winpty) docker container exec -it client_client_1 bash を実施して、

root@d561a99d0f67:/go/src/client# go run client.go

を実施したら、

connecting to ws://localhost:8080/echo
dial:dial tcp 127.0.0.1:8080: connect: connection refused
exit status 1

となりました。このlocalhostは、コンテナ内のホストだから、コンテナの外にあるホストOSや、別のコンテナの中にあるサーバには、繋らないんだろうなぁ、と。

その証拠に、

root@d561a99d0f67:/go/src/client# ping kobore.net
PING kobore.net (49.212.198.156) 56(84) bytes of data.
64 bytes from 49.212.198.156 (49.212.198.156): icmp_seq=1 ttl=37 time=12.0 ms

と、外部には、バッチリ繋っている(でも、これは、ちょっと凄いと思う)


では、ここからトライアル。

docker-compose.ymlの最後に、

extra_hosts:
- "local_dev:192.168.0.1"

を追加 → 失敗。 ちなみに、"127.0.0.1"も失敗しました。

もしからしたら、と思い、 extra_hosts:をコメントアウトして、client.goの方のアドレスを直書きしてみました。今、PC本体のアドレスが、

C:\Users\ebata>ipconfig

Windows IP 構成

イーサネット アダプター イーサネット:

接続固有の DNS サフィックス . . . . .:
IPv4 アドレス . . . . . . . . . . . .: 192.168.0.8
サブネット マスク . . . . . . . . . .: 255.255.255.0
デフォルト ゲートウェイ . . . . . . .: 192.168.0.1

なので、client.goの一行を以下のように換えてみました。

//var addr = flag.String("addr", "localhost:8080", "http service address")
//var addr = flag.String("addr", "0.0.0.0:8080", "http service address")
var addr = flag.String("addr", "192.168.0.8:8080", "http service address")

これで動きましが、正直、なんとも気持ち悪いです。

ただ、これを解決するためには、dockerでIPフォワーディングとかやらなければならないのだと思うと、結構ウンザリした気分になりましたので、このままで放置することにします(動けばいいんですよ。ここは踏んばるところではありません)

以上

2020/08,江端さんの技術メモ

前提の記事はこちら

このサーバをさらにDockerのコンテナに搭載します。

サーバも何も入っていないが、Golang開発環境だけが入っているコンテナを作ります。DockerでGoの開発環境を構築するを参考させて頂きました。

mkdir work # workディレクトリ作成
cd work # 作成したworkディレクトリに移動

ここに、Dockerfileとdocker-compose.ymlを作ります。

(Dockerfileの内容)
# ベースとなるDockerイメージ指定
FROM golang:latest
# コンテナ内に作業ディレクトリを作成
RUN mkdir /go/src/work
# コンテナログイン時のディレクトリ指定
WORKDIR /go/src/work
# ホストのファイルをコンテナの作業ディレクトリに移行
ADD . /go/src/work

上記の、/go/src/work は、ローカル(PC)のディレクトリではなくて、コンテナの中のディレクトリなので、パスの構成は気にしなくてよい。

(docker-compose.yml
の中身)
version: '3' # composeファイルのバーション指定
services:
  app: # service名
    build: . # ビルドに使用するDockerfileがあるディレクトリ指定
    tty: true # コンテナの起動永続化
    volumes:
      - .:/go/src/work # マウントディレクトリ指定

次に、

docker-compose build

を実行する。

$ docker-compose build
Building app
Step 1/4 : FROM golang:latest
 ---> a794da9351a3
Step 2/4 : RUN mkdir /go/src/work
 ---> Using cache
 ---> 094b928e9bfb
Step 3/4 : WORKDIR /go/src/work
 ---> Using cache
 ---> b7a938d02446
Step 4/4 : ADD . /go/src/work
 ---> 9d95f42d64e3
Successfully built 9d95f42d64e3
Successfully tagged work_app:latest

さらに、docker-compose up -d を実行する。

$ docker-compose up -d
Creating network "work_default" with the default driver
Creating work_app_1 ... done

コンテナができているか同化を確認します。

$ docker-compose ps
   Name      Command   State   Ports
------------------------------------
work_app_1   bash      Up

現在、~/go_echo にある、server.goを、~/go_echo/workにコピーします。

これで、server.go が、ローカル(PC)と、コンテナの中で共有されるようになります。

では、コンテナの中に入ります。

$ winpty docker container exec -it work_app_1 bash # 江端のMSYS2 のシェルでは、"winpty"を付ける必要があるが、通常のシェルでは不要

root@abe44622eccf:/go/src/work# ls
'#main.go#'   Dockerfile   Dockerfile~   server.go   docker-compose.yml   docker-compose.yml~   main   main.go   main.go~   websocket-server.go

ここで、Goプログラムを実行します。

root@abe44622eccf:/go/src/work# go run server.go
server.go:21:2: cannot find package "github.com/gorilla/websocket" in any of:
        /usr/local/go/src/github.com/gorilla/websocket (from $GOROOT)
        /go/src/github.com/gorilla/websocket (from $GOPATH)

ふむ、やはり、こうなりますね。では、パッケージをインストールしましょう。

root@abe44622eccf:/go/src/work#  go get github.com/gorilla/websocket

何のメッセージも出さずに20秒後くらいに静かにプロンプトが戻ってきました(ちょっと不安になる)。

root@abe44622eccf:/go/src/work# go run client_multi_agent.go
connecting to ws://localhost:8080/echo
dial:dial tcp 127.0.0.1:8080: connect: connection refused
exit status 1

うーん、やっぱりネットワーク回りの設定をしていないから当然か。ポート開けていないし。docker-compose downして、docker-compose.ymlに以下を追加してみました。

ports:
  - "8080:8080"
$ more docker-compose.yml
version: '3' # composeファイルのバーション指定
services:
  app: # service名
    build: . # ビルドに使用するDockerfileがあるディレクトリ指定
    tty: true # コンテナの起動永続化
    volumes:
      - .:/go/src/work # マウントディレクトリ指定
    ports:
      - "8080:8080"

それと、"go get github.com/gorilla/websocket"を毎回実行しない為には、Dockerfileに "RUN go get github.com/gorilla/websocket"を1行加えれば良いみたい。

# ベースとなるDockerイメージ指定
FROM golang:latest
# コンテナ内に作業ディレクトリを作成
RUN mkdir /go/src/work
# コンテナログイン時のディレクトリ指定
WORKDIR /go/src/work
# ホストのファイルをコンテナの作業ディレクトリに移行
ADD . /go/src/work

# gorillaのパッケージを入れる
RUN go get github.com/gorilla/websocket

そんでもって、再びdocker-compose build → docker-compose up -d を実施して、docker container exec -it work_app_1 bash をして、コンテナの中に入って、go run server.goをやったんだけど、ブラウザで、http://localhost:8080やっても表示されない。

C:\Users\ebata\go_echo\work>curl http://localhost:8080/
curl: (52) Empty reply from server

となっているところを見ると。8080ポートは外側に見えていないみたい。

でも、

C:\Users\ebata\go_echo\work>netstat -a | grep 8080
  TCP         0.0.0.0:8080           DESKTOP-P6KREM0:0      LISTENING
  TCP         [::]:8080              DESKTOP-P6KREM0:0      LISTENING

にはなっているんだよなぁ。

試しに、コンテナの中で"curl http://localhost:8080/"をやってみたら、

oot@b30e685f9cc6:/go/src/work# curl http://localhost:8080/

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
window.addEventListener("load", function(evt) {
    var output = document.getElementById("output");
    var input = document.getElementById("input");
    var ws;

てな感じで、ばっちり見えます。

うーん、変だなぁ。"8080:8080"ってポートフォワードしているじゃないのか? WebSocketの場合は、特殊な設定がいるのか?分かりません。

もう6時間くらい闘ったので、引き上げようとして、最後に、"curl: (52) Empty reply from server" でググってみたら、ドンピシャな感じの記事を見つけました。

docker上のアプリにlocalhostでアクセスしたらERR_EMPTY_RESPONSEが出る

まさに、同じ現象が表われていて、『そう! そう!』と言いながら読み進めていき、結果として、

(解決) アプリの設定を0.0.0.0でLISTENするよう変更する

と記載されていましたので、server.goのソースコードを、

//var addr = flag.String("addr", "localhost:8080", "http service address")
var addr = flag.String("addr", "0.0.0.0:8080", "http service address") // テスト

と変更してみたところ、http://localhost:8080 でWebもcurlも表示されるようになりました。

ああ、これで、サーバのコンテナ化にメドがついた ―― と思ったら、どっと疲れが出てきました。

『Dockerのコンテナは、江端が作れ』と、指示されていましたので。


Dockerfileの最後に、

CMD ["go", "run", "server.go"]

をつけると、dockerコンテナをサーバ化にできる。

ただし、

# docker-compose build, 
# docker-compose up (-d ← これを付けたらダメ。バックグラウンドで起動するとDockerが終了してしまう)

で起動すること。

2020/08,江端さんの忘備録

「やはり俺の青春ラブコメは間違っている完」の第7話の視聴後感想になります。

This is my impression after watching episode 7 of "My Youth Romantic Comedy is Wrong,As I Expected -- Final"

「意識高い系」という言葉があります。

There's a word for "self-aware".

やたら会話の中に、横文字を使ったりする人を揶揄する言葉のようです。

It seems to be a term of ridicule for people who use English-words in conversation.

で、その「意識高い系」の言葉を、ちょっと調べてみたんですが、

So, I did some research on that word "self-aware".

アサイン、エビデンス、コミットメント、ジャストアイディア、ゼロベース、サマリー、タイト、デフォルト、フィックス、プライオリティ・・・

Assign, Evidence, Commitment, Just Ideas, Zero-Based, Summary, Tight, Default, Fix, Priority...

うーん、これらの使用を禁止されると、色々困ります。

Hmmm, if I am banned from using these, I am in a lot of trouble.

特に、特許ブレスト(これも、特許アイデア検討会、と言うべきか)が、できなくなります。

In particular, I will not be able to have a patent brainstorming session (or should I say, a patent idea review session).

しかし、これらの言葉を使うことで、不愉快に感じる人もいるだろうとも思います。

However, I also think some people may find the use of these words offensive.

「用語の勘違い」という問題あります。例えば、以前、「アバター」のことを、「痘痕(あばた)」と勘違いされて、怒られたこともありました。

There's a problem of "misunderstanding of terms". For example, I once got angry when someone mistook "avatar" for "pockmark".

まあ、これらの用語はTPOに合わせて、使い分けることが大切なのだと思います。

Well, I think it's important to use these terms in accordance with the TPO.

----

私としては、むしろ、

As for me, I'd rather exterminate people

「AI系」: デジタルサービスを、なんでもかんでも、"AI"と言ってしまう奴

"who use the term "AI" to refer to all kinds of digital services"

を絶滅させたい。

『それって、"AI"で動いているから・・』

"It's powered by an AI.so.."

『待った。その"AI"ってどの技術のこと? 機械学習? ニューラルネットワーク? 統計解析? それとも、それ以外?』

"Wait. What technology is this "AI" you're talking about? Machine learning? A neural network? Statistical analysis? Or else?"

などと言えば、嫌われるだろうなぁ。もう手遅れだろうけど。

If I say something like that, everyone will hate me. It will be too late, though.

-----

『"政治"が悪いんだよ!』

"Bad politics!"

『待った。その"政治"ってどの分野のこと? 財政? 福祉? 軍事? 外交? 教育? それとも対象かな。与党? 野党? それとも省庁のことかな。そうだとしたら、その省ってどれ?』

"Wait. What field is this "politics" in? Finances? Welfare? Military? Diplomacy? Education? Or is it the target. The ruling party? Opposition? Or maybe it's the ministry. And if so, which one is that ministry?"

うん、私も、こういうこと言う奴、嫌いだ。

Yeah, I don't like people who say these things either.

2020/08,江端さんの忘備録

2020年8月22日の10:41ごろに、私のコラムをご愛読頂いている方から、質問のメールを頂きました。

On August 22, 2020, at about 10:41 a.m., I received an email from a reader of my column with a question.

私も直ぐに答えられなかったので、ここ1~2日、ちゃんと考えた上で、ブログでお返事することにしました。

I couldn't answer right away either, so I've been thinking about it for a day or two and decided to respond to him on my blog.

=====================

(Q1)江端さんのコラムの分野は、多岐に渡っていますが、どのように情報収集をされていますか?

(Q1) Your columns cover a wide range of subjects. How do you gather information?

=====================

私は、定期的な情報収集はやっていません。

I don't do regular information gathering.

コラムは基本的には1月に1回リリースとなりますので、この一月の間で、狂ったように、コラムに関連する情報収集をやっています。

The column will basically be released once a month in January, so I've been doing a crazy amount of information gathering over the past month.

------

インターネットの検索エンジンを使えば、そこそこの情報は手に入りますが、ニュースや個人のブログよりは、"Google Scholar(論文検索)"を頻用しています。

I can get a lot of information by using Internet search engines. and I use "Google Scholar" (paper search) more frequently than news and personal blogs.

良質のデータ、理路整然としたロジック、非凡な問題への着眼点という点では、論文は、頭2つ分くらいは抜けている感じがします。

In terms of good quality data, methodical logic, and a focus on extraordinary problems, papers are outstanding.

とは言え、論文の文章は難解なので「ななめ読み」を心掛けています。

Nevertheless, I try to "lickety-split" because the text of the paper is difficult to understand.

詳しくは、こちらの方法が参考なると思います。

For more information, this is how you can help.

-----

論文以外では、やはり書籍(本)です。

Other than papers, it's still books.

お金がないので、市営図書館の予約システムを使って本を借りまくっています。

Since I don't have the money, I use the city library's reservation system to borrow books.

予約が間にあわないと判断すれば、自腹を切って、Amazonで書籍を購入しています。

If I decide that I can't make it in time with a reservation, I pay my own way and buy the book on Amazon.

最近は電子書籍が便利だと感じています。

I've found ebooks to be very useful these days.

電子書籍は、PCのディスプレイで本を読みながら、原稿が書けるので、大変重宝しています(ですので、私の部屋では、4台のPCディスプレイ常に起動状態です)

E-books are very useful because I can write a manuscript while reading a book on my PC display (so in my room, I have four PC displays running at all times).

しかし、専門書は値段が高いので、頭痛の種でもあります。

However, specialty books are expensive, and that's a headache.

-----

最近の私が頻用しているのは、YouTubeです。

One thing I use frequently these days is YouTube.

「量子コンピュータ」や「量子論」に関するYouTubeのコンテンツは秀逸です。

The YouTube content on "quantum computers" and "quantum theory" is excellent.

大学の先生や、予備校の講師によるYouTubeの講義は、映像と併わせて説明をして貰える上に、分からないところでは止めることができ、何度も繰返して視聴できる点が、大変素晴しいです。

The lectures on YouTube, given by university professors and lecturers from prep schools, are excellent because the lectures are explained along with videos, I can stop and watch them over and over again if I cannot understand something,.

一般的に、分かりやすいコンテンツは、視聴者数が多いですので、視聴の前に、コンテンツの品質を評価できる点も良いです。

In general, content that is easy to understand has a larger audience, so it's good to be able to assess the quality of the content before I watch it.

-----

その他としては、漫画コミックは、社会、行政、医療、福祉、障がい、法律、LBGT、科学技術など、情報の宝庫です。

Otherwise, comic books are a treasure trove of information on social, government, medical, welfare, handicap, law, LBGT, science and technology, and more.

また、ハードSF小説などは、先端技術のてんこ盛りです。

Also, hard science fiction novels, for example, are a pile of advanced technology.

-----

あと、「メールで連絡して頂いた方から、直接教えて頂く」ことや、「有識者の方のお宅まで行く」こともあります。

Also, I have "people who contacted us by email to tell him/her directly" and sometimes I go to the homes of experts.

これまで、LGBTの方から直接色々教えて頂きましたし、医療や法律や技術やコンテンツの創作者の方にインタビューに参上したこともあります。

I've learned a lot of things directly from LGBT people, and I've attended interviews about medicine, law, technology and content creators .

インタビューの前に『御礼はお支払いできないですけど、いいですか』と伺うのですが、これを理由に断わられたことは、今のところありません。

I ask before the interview, "I am sorry but I can't pay you for your help", however I've never been rejected by this reason.

-----

これは情報収集ではありませんが、「コンピュータプログラミング & シミュレーション」は、私にとって、最強の味方でありますが、同時に、最悪の敵でもあります。

This isn't information gathering, but "Computer Programming & Simulation" is my strongest ally, but also my worst enemy.

このシミュレーションの結果によって、却下を余儀なくされた私の仮説には、枚挙にいとまがありません。

A number of my hypotheses have been rejected by the results of this simulation.

==========

Q2:定期的に購読している雑誌やサイト、新聞はありますか?

Q2: Are there any magazines, websites or newspapers that you regularly subscribe to?

==========

私は、定期購読はしていません。

I do not have a subscription.

私が必要としている時に、必要な情報が入手できるわけではありませんし、必要な時にバックナンバーを入手すれば良いからです(ただし、バックナンバー入手できないケースも多いですが)。

I don't have access to the information when I need them, and I can get back issues when I need them (although in many cases I can't get back issues).

ただ、定期的にNHKスペシャルは見るようにしています。必要なら、NHKアーカイブスにお金を払って見ています。

However, I try to watch the NHK specials on a regular basis. If I have to, I pay for the NHK archives to watch them.

しかし、NHKスペシャルは、受信料を払っていても、NHKアーカイブズを使っても、過去の全てのコンテンツが見れる訳ではなく、正直、不満はあります。

However, even if I pay a subscription fee or use the NHK archives, I can't watch all of the past content of the NHK Special. Honestly, I'm not happy with it.

新聞については、嫁さんが、契約用の米やら洗剤や遊園地にチケット欲しさに、定期的に新聞を換えてしまうので、「不定期購読」をしているという状況です。

As for the newspapers, I am in a situation where I have an "irregular subscription" because my wife changes newspapers regularly because she wants rice, detergent and tickets to the amusement park with the contracts.

故に、私は、こういう日記が書けます。

Hence, I can write this diary.

以上です。

That's all.

-----

当方のコラムをご愛読頂き、誠にありがとうございます。

Thank you for reading my columns.

今後とも、引き続き、ご購読頂けましたら、幸甚と存じます。

I would be grateful if I could continue to subscribe to my works.

江端智一

Best regards,

Tomoichi Ebata.

江端さんの忘備録

最近、新聞のチラシ広告に、

Recently, in a leaflet advertisement in a newspaper, I can find a paper,

「役所で使っていた型落ちのPCの即売会」

"Sold-out party of unfashionable PC used at the government office"

を見つけます。

このようなチラシが入っていれば、格安でPCが手に入るような錯覚になりますが、

If you read such a leaflet, you may get the illusion that you can get a PC at a cheap price.

――その値段であれば、同程度以上のPCが新品が買える

"If it is that price, you can buy a new PC of the same level or more"

というくらい、最近のPCのコストは安いです。

Recent PC prices becomes low like that.

-----

もっとも、電気量販店での店頭価格を比較にしてはダメです。

However, it is not good to compare the retail price at an electric retailer.

DELL, Lenovoなどの、有名どころの通販サイトを知っていなければなりません。

You must know famous mail order sites such as DELL and Lenovo.

加えて「納期3週間」という、発注時に製造が開始される「受注生産」を覚悟しなければなりません。

In addition, you have to be prepared for "made-to-order manufacturing" in which production is started at the time of ordering, with "delivery time of 3 weeks".

それはさておき。

Set it asaide.

-----

私が、安いPCの取得方法を教えてしまったら、その人は、幸せを感じることができなくなります。

If I tell him/her how to get the cheaper PC, He/She doesn't come to feel happiness,

それ故、知っている人は、知らない人に、賢しく騒ぎたてるべきではないでしょう。

Therefore, a person who know well, should not make a lot of noise with bright-faced to a person who don't know well.

私にしたって、IT回りに詳しいだけで、多分他のことでは、「役所で使っていた型落ちのPC」のようなものを買いまくっていると思います ――

For me, I know about IT well by accident. However I don't know many things in the world, and I have bought something lke "unfashionable PC used at the government office"

例えば、不動産とか、保険契約とか、愛とか、愛や、愛です。

For example, estate, agreement for insurance and love and love or love.

「『無知の無知』という幸せを、幸せのままにしておく」という配慮は、あって然るべきです。

You should be thoughtful of keeping "Ignorance is bliss" of others.

2020/08,江端さんの忘備録

3年前にリリースした国際学会のカンファペーパーに関して、論文化のオファを受けました。

I received an offer to make a paper on the international conference paper I released three years ago.

調べてみたところ、身元もしっかりしていて、SPAMでも広告詐欺でもないようです。

I looked it up and it appears to be a solid identity and not SPAM or an ad scam.

しかし、一つ疑問なのが、オファされた論文のフィールドです。

One question, however, is the field of the offered paper.

―― 「哲学的取引 (Philosophical Transaction)」

"Philosophical Transaction"

-----

哲学とは、「人生・世界、事物の根源のあり方・原理を、理性によって求めようとする学問、あるいは経験からつくりあげた人生観」であるので、これも「技術」の一態様であるとは思っています。

Philosophy is, "the study of life, the world, and the principles of the origin of things, or a view of life created from experience", so I believe this is another form of "technology".

ですので、私は、哲学に高尚なイメージは持っていませんが、この件については、凄い違和感を感じています。

So I don't have a lofty image of philosophy, but I do feel a terrific sense of discomfort about this offer.

まあ、最近の私の研究「人間の不満(怒り)を数値化して、システム運用に取り込む」という独自アプローチは、「哲学の分野」と言えなくはないのかもしれません。

Well, my recent work on my original approach to "quantifying human dissatisfaction (anger) and incorporating it into system operations" may be a "field of philosophy".

-----

ともあれ、意外なところからの、意外なオファでした。

Anyway, it was an unexpected offer, from an unexpected office.

『なかなか面白いイベントが飛んできたなぁ』と、ちょっと笑いました。

"That's quite an interesting event to fly in"

I was laughing a bit.

2020/08,江端さんの忘備録

そもそも私、会社でも、ひとり実験室に閉じ込もって、特許明細書、報告書、コーディング、システム構築を行っていました。

To begin with, I was locked in a lab by myself, even at the company office, writing patent specifications and reports, coding, building a system.

コロナ禍が始まる前から、私は「会社の中で在宅勤務している」ようなものでした。

Even before the Corona disaster started, I was sort of "working at home in the office".

それでも、会議とか出張などが、私を、実験室の外側へと引き剥していました。

Still, meetings and business trips were pulling me out of the lab.

-----

最近の、在宅勤務のおかげで、労働時間が増加しています。

These days, thanks to telecommuting, working hours are increasing.

とは言え、私の場合、業務と趣味が、"0猫"と"1猫"の量子状態ですので、実質な労働時間を、正確に「観測」することができませんが。

However, in my case, my work and hobbies are in the quantum state of "0 cat" and "1 cat", so I can't "observe" the real working hours with any accuracy.

とにかく、「切れ目」が見つからないので、ぶっつづけで、システム構築をやり続けることができてしまいます。

Anyway, since I can't find a "break point" during working time, I can just keep on building a system.

報告書や特許明細書やカンファレンスペーパーなども、予定通り、遅滞なく提出していました。

Reports, patent specifications and conference papers were also submitted on time and without delay.

これも、私の徹底的な「アンチ・チームプレーの精神」に基づく成果だなぁ、と、しみじみと感じ入っています。

I feel deeply that this is another result of my thoroughgoing "anti-team-playing" spirit,

-----

しかしながら、体調の方も、着実に崩れてきています。

今の私は、

However, my physical condition is falling down certainly.

「ぼっち属性」+「強制的な在宅勤務」+「パソコン3台とディスプレイ5台が同時に起動しているIT環境」

"solitary attributes" + "forced telecommuting" + "IT environment with three computers and five displays running at the same time

is equal to

= 「慢性的な疲労状態」

"chronic fatigue".

という等式の中にいます。

is established now.

2020/08,江端さんの忘備録,江端さんの技術メモ

Go言語は、スレッド化による並列処理が得意という話を聞いていましたので、先日の

の"client.go"を改造して、「とりあえず、動かして、止めることができればいい」という割り切りだけでコードをごそごそを変えてみました。(server.goは変更なしで大丈夫)。 ファイルは、~/go_echo/に置くこととします。

// go run client_multi_agent.go

// Copyright 2015 The Gorilla WebSocket Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build ignore

package main

import (
	"flag"
	"log"
	"net/url"
	"os"
	"os/signal"
	"time"

	"github.com/gorilla/websocket"
)

var addr = flag.String("addr", "localhost:8080", "http service address")


var interrupt = make(chan os.Signal, 1) // Go のシグナル通知は、チャネルに os.Signal 値を送信することで行います。
			  	 		   			  	 // これらの通知を受信するためのチャネル (と、プログラムが終了できること
										 // を通知するためのチャネル) を作ります。
var	u = url.URL{Scheme: "ws", Host: *addr, Path: "/echo"} // JSON型の配列記述方法?

func main() {
	flag.Parse()     //引数の読み込み argv, argcと同じ
	log.SetFlags(0)  // ログの出力で時間の情報、この時点で0秒にセット

//	interrupt := make(chan os.Signal, 1) // Go のシグナル通知は、チャネルに os.Signal 値を送信することで行います。
//			  	 		   			  	 // これらの通知を受信するためのチャネル (と、プログラムが終了できること
//										 // を通知するためのチャネル) を作ります。

	signal.Notify(interrupt, os.Interrupt) // 指定されたシグナル通知を受信するために、 与えられたチャネルを登録
							 			   // します。

	log.Printf("connecting to %s", u.String()) // ここは単にプリントしているだけ(だろう)

	///// ここまでは共通 /////

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		

	go sub_main()
	time.Sleep(time.Millisecond * 333)  // 333ミリ秒		
	
	ticker := time.NewTicker(time.Second)  // 1秒おきに通知 (sleepと同じ)		

	for {
		select{
    	   case <-ticker.C: // tickerのチャネルはデフォルトで付いているらしい
		   case <-interrupt:  // こっちは手動割り込みだな検知だな
		        return;
		}
     }
}

func sub_main(){
	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil) // これがコネクションの実施
	if err != nil {
		log.Fatal("dial:", err)
	}
	defer c.Close() // deferは、どこに書かれていようとも、関数から抜ける前に実行される

	done := make(chan struct{}) // 配列といってもいいし、並行処理用のキューといってもいい
                                // 値が入っていないとデッドロックする

	go func() {  // 受信用スレッドを立ち上げる(スレッドの中でスレッド立ち上げているが、大丈夫だろうか)
		defer close(done)
		for {
			_, message, err := c.ReadMessage() // このメソッドの返り値は3つで、最初の返り値は不要
			if err != nil {
				log.Println("read:", err)
				return
			}
			log.Printf("recv: %s", message)  // 受信したら、そのメッセージを表示する
		}
	}()

	ticker := time.NewTicker(time.Second)  // 1秒おきに通知 (sleepと同じ)
	defer ticker.Stop() // このループを抜ける時に終了する

	for {            // 無限ループの宣言かな(C/C++ で言うとろの、whileとかdoとか)
		select {
		case <-done: // doneの中に何かが入っていたら、このルーチンはリターンして終了となる
			 		 // (でも何も入っていないところを見ると、func()ルーチンの消滅で、こっちが起動するんだろう)
			return
		case t := <-ticker.C: // tickerのチャネルはデフォルトで付いているらしい
			   	  			  // 時間が入ってくるまでロックされる	 
			   	  			  // この場合1秒単位でチャネルに時間が放り込まれるのでそこで動き出す。

			err := c.WriteMessage(websocket.TextMessage, []byte(t.String())) // サーバに(時刻の)メッセージを送付する
			if err != nil {
				log.Println("write:", err)
				return
			}
		case <-interrupt:  // こっちは手動割り込みだな検知だな
			log.Println("interrupt")

			// Cleanly close the connection by sending a close message and then
			// waiting (with timeout) for the server to close the connection.

			// close メッセージを送信してから、サーバーが接続を閉じるのを
			// (タイムアウトして)待つことで、接続をきれいに閉じます

			err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
			if err != nil {
				log.Println("write close:", err)
				return
			}
			select {
				case <-done: // これも上記の"done"の説明と同じでいいかな
				case <-time.After(time.Second): // このメソッド凄い time.Secondより未来ならひっかかる
			}
			return
		}
	}
}

まあ、main()と sub_main()で同じ割り込みを使っているので、タイミングによっては、main()を止めることができず、sub_main()を個別に止めていくことになるが、とりあえず動いたので、これで良しとする。

go sub_main() と書くだけで、いきなりスレッド化させることができる手軽さは、かなり驚いた。

こんなんやこんなんで、いろいろ苦労してきたんだけど、これからも、マルチエージェントシミュレーションを自力で書いていくことを考えると、正式にGo言語に移るべきかな、と思っています。

go webassembly experiments をローカルPCで動かす とかも、いろいろやっていきたいことですし。

2020/08,江端さんの忘備録

「命短し、恋せよ乙女」というフレーズには続きがあります。

There is a continuation of the phrase "Life is short, fall in love, maiden"

♪いのち短し、恋せよ乙女、あかき唇、あせぬ間に

"Life is short, fall in love, maiden, before the red lips fade away"

♪いのち短し、恋せよ乙女、黒髪の色、あせぬ間に

"Life is short, fall in love, maiden, before the black hairs fade away"

このフレーズを見てみると、なかなか辛辣なフレーズのようです。

When I look at the phrase, it seems to be quite a harsh phrase.

今なら、セクハラの類(たぐい)に入るかもしれません。

Now, it might be a kind of sexual harassment.

-----

しかし、私の数値解析結果によれば、このフレーズは、

However, according to my numerical analysis, the phrase should be changed with

「命短し、恋せよ男」

"Life is short, fall in love, men"

という方が相応しいように思えます。

定量的には、"乙女"より、"男"の方が、2倍ほど事態が深刻です。

Quantitatively, the situation is twice as serious for a "man" than for a "maiden".

-----

という訳で、ちょっとフレーズを改造してみました。

So I modified the phrase a bit.

♪命短し、恋せよ男、臭き口臭、常ならぬ間に

"Life is short, fall in love, men, before stinky breath becomes a regular"

♪命短し、恋せよ男、少き頭髪、抜けぬ間に

"Life is short, fall in love, men, before a few heads of hair fall out"

-----

男の経年劣化は、女性よりダイナミックに発現します(本当)。

Men's deterioration over time occurs more dynamically than women's (true).

そして、その変化を補う手段は、女性と比べて絶望的に少ないです(事実)。

And the means to compensate for the change are hopelessly less than for women (in fact).