2022/03,江端さんの技術メモ

Sync.Cond、broadcastを使うには、条件があるようです

の、最後に記載した、

そういえば、ブロードキャストの送信者が1であった場合は問題がなかったけど、今回は、送信者が3になったところから、変な動きをしだしたことから鑑みて、

送信者、受信者は1:Nの関係でないとだめ

なのかもしれないです。

として、別方式を考えているのですが、「Goの複数のgoroutineに対する、一斉ブロードキャスト」の便利さが、どうにも諦めきれなくて、まだ調べています。

そこで、簡易プログラムで以下の検証を行いました。

目的は以下の通り。

・送信者(sender)(ただし1人)や、受信者(receiver)がランダムなタイミングで出現・消滅しても、ちゃんと動くか

を検証してみました。

// go run main3.go
/*
	boardcast sync.bc 実験
	(1) 送信側(sender)をgoroutineにて大丈夫か
	(2) 受信側(sender)のgoroutineを、送信側の前後で、
	適当なタイミングで生成して、消滅させても大丈夫か
*/

package main

import (
	"fmt"
	"log"
	"math/rand"
	"sync"
	"time"
)

type BroadCaster struct {
	cond *sync.Cond
	id   int64
	msg  string
}

func (bc *BroadCaster) Send(msg string) {
	bc.cond.L.Lock()
	defer bc.cond.L.Unlock()
	bc.id++
	bc.msg = msg
	bc.cond.Broadcast()
}

func (bc *BroadCaster) Recv(last int64) (int64, string) {
	bc.cond.L.Lock()
	defer bc.cond.L.Unlock()
	for bc.id == last {
		bc.cond.Wait()
	}
	return bc.id, bc.msg
}

var (
	broadcaster = &BroadCaster{
		cond: sync.NewCond(&sync.Mutex{}),
	}
)

func receiver(i int) {

	delete_count := 5 + rand.Intn(10) // ループ回数は5~14回のどれか

	log.Println("recv:", i, " start")
	defer log.Println("recv:", i, " stop")

	last := int64(0)
	for k := 0; k < delete_count; k++ {
		id, msg := broadcaster.Recv(last)
		last = id
		log.Println("recv:", i, msg)
	}

}

func sender() {
	for i := 0; i < 20; i++ { // 20回程度送ってみる
		time.Sleep(1 * time.Second)
		broadcaster.Send(fmt.Sprintf("hello, world: %d", i))
	}
}

func main() {
	for i := 0; i < 3; i++ {
		go receiver(i)
	}

	/*
		for i := 0; i < 100; i++ {
			time.Sleep(1 * time.Second)
			broadcaster.Send(fmt.Sprintf("hello, world: %d", i))
		}
	*/

	go sender()

	for i := 4; i < 6; i++ {
		go receiver(i)
		time.Sleep(1 * time.Second)
	}

	time.Sleep(100 * time.Second) // 排他処理を書くのが面倒なので、ここでmainを眠らせておく

}

これで得られた結果です。

c:\Users\ebata\goga\1-7\test>go run main3.go
go run main3.go
go run main3.go
2022/03/18 12:39:02 recv: 0  start
2022/03/18 12:39:02 recv: 2  start
2022/03/18 12:39:02 recv: 4  start
2022/03/18 12:39:02 recv: 1  start
2022/03/18 12:39:03 recv: 1 hello, world: 0
2022/03/18 12:39:03 recv: 4 hello, world: 0
2022/03/18 12:39:03 recv: 2 hello, world: 0
2022/03/18 12:39:03 recv: 0 hello, world: 0
2022/03/18 12:39:03 recv: 5  start
2022/03/18 12:39:03 recv: 5 hello, world: 0
2022/03/18 12:39:04 recv: 4 hello, world: 1
2022/03/18 12:39:04 recv: 5 hello, world: 1
2022/03/18 12:39:04 recv: 2 hello, world: 1
2022/03/18 12:39:04 recv: 0 hello, world: 1
2022/03/18 12:39:04 recv: 1 hello, world: 1
2022/03/18 12:39:05 recv: 5 hello, world: 2
2022/03/18 12:39:05 recv: 1 hello, world: 2
2022/03/18 12:39:05 recv: 4 hello, world: 2
2022/03/18 12:39:05 recv: 2 hello, world: 2
2022/03/18 12:39:05 recv: 0 hello, world: 2
2022/03/18 12:39:06 recv: 1 hello, world: 3
2022/03/18 12:39:06 recv: 5 hello, world: 3
2022/03/18 12:39:06 recv: 4 hello, world: 3
2022/03/18 12:39:06 recv: 2 hello, world: 3
2022/03/18 12:39:06 recv: 0 hello, world: 3
2022/03/18 12:39:07 recv: 0 hello, world: 4
2022/03/18 12:39:07 recv: 4 hello, world: 4
2022/03/18 12:39:07 recv: 2 hello, world: 4
2022/03/18 12:39:07 recv: 5 hello, world: 4
2022/03/18 12:39:07 recv: 1 hello, world: 4
2022/03/18 12:39:08 recv: 1 hello, world: 5
2022/03/18 12:39:08 recv: 4 hello, world: 5
2022/03/18 12:39:08 recv: 0 hello, world: 5
2022/03/18 12:39:08 recv: 5 hello, world: 5
2022/03/18 12:39:08 recv: 0  stop
2022/03/18 12:39:08 recv: 5  stop
2022/03/18 12:39:08 recv: 2 hello, world: 5
2022/03/18 12:39:09 recv: 2 hello, world: 6
2022/03/18 12:39:09 recv: 1 hello, world: 6
2022/03/18 12:39:09 recv: 4 hello, world: 6
2022/03/18 12:39:10 recv: 4 hello, world: 7
2022/03/18 12:39:10 recv: 2 hello, world: 7
2022/03/18 12:39:10 recv: 1 hello, world: 7
2022/03/18 12:39:11 recv: 1 hello, world: 8
2022/03/18 12:39:11 recv: 4 hello, world: 8
2022/03/18 12:39:11 recv: 2 hello, world: 8
2022/03/18 12:39:12 recv: 2 hello, world: 9
2022/03/18 12:39:12 recv: 4 hello, world: 9
2022/03/18 12:39:12 recv: 1 hello, world: 9
2022/03/18 12:39:13 recv: 1 hello, world: 10
2022/03/18 12:39:13 recv: 2 hello, world: 10
2022/03/18 12:39:13 recv: 4 hello, world: 10
2022/03/18 12:39:14 recv: 4 hello, world: 11
2022/03/18 12:39:14 recv: 1 hello, world: 11
2022/03/18 12:39:14 recv: 1  stop
2022/03/18 12:39:14 recv: 2 hello, world: 11
2022/03/18 12:39:14 recv: 4  stop
2022/03/18 12:39:15 recv: 2 hello, world: 12
2022/03/18 12:39:16 recv: 2 hello, world: 13
2022/03/18 12:39:16 recv: 2  stop

結論としては、

・recvierは、データを重複することなく、またロストすることなく、1つづつキレイに受けとっていた

ということになります。


さて、ここで、今度は、送信者を2人にしてみます。送信者の名前が見易いように、"111"と"999"の番号を付けてます(冗長ですが、プログラムリスト全部を掲載します(私の為に))

// go run main3.go
/*
	boardcast sync.bc 実験
	(1) 送信側(sender)のgoroutineを2つにしたらどうなるか
*/

package main

import (
	"fmt"
	"log"
	"math/rand"
	"sync"
	"time"
)

type BroadCaster struct {
	cond *sync.Cond
	id   int64
	msg  string
}

func (bc *BroadCaster) Send(msg string) {
	bc.cond.L.Lock()
	defer bc.cond.L.Unlock()
	bc.id++
	bc.msg = msg
	bc.cond.Broadcast()
}

func (bc *BroadCaster) Recv(last int64) (int64, string) {
	bc.cond.L.Lock()
	defer bc.cond.L.Unlock()
	for bc.id == last {
		bc.cond.Wait()
	}
	return bc.id, bc.msg
}

var (
	broadcaster = &BroadCaster{
		cond: sync.NewCond(&sync.Mutex{}),
	}
)

func receiver(i int) {

	delete_count := 5 + rand.Intn(10) // ループ回数は5~14回のどれか

	log.Println("recv:", i, " start")
	defer log.Println("recv:", i, " stop")

	last := int64(0)
	for k := 0; k < delete_count; k++ {
		id, msg := broadcaster.Recv(last)
		last = id
		log.Println("recv:", i, msg)
	}

}

func sender(i int) {
	for k := 0; k < 20; k++ { // 20回程度送ってみる
		time.Sleep(1 * time.Second)
		broadcaster.Send(fmt.Sprintf("hello, world: %d from %d", k, i))
	}
}

func main() {
	for i := 0; i < 3; i++ {
		go receiver(i)
	}

	/*
		for i := 0; i < 100; i++ {
			time.Sleep(1 * time.Second)
			broadcaster.Send(fmt.Sprintf("hello, world: %d", i))
		}
	*/

	go sender(111) // ここに注意
	go sender(999) // ここに注意

	for i := 4; i < 6; i++ {
		go receiver(i)
		time.Sleep(1 * time.Second)
	}

	time.Sleep(100 * time.Second) // 排他処理を書くのが面倒なので、ここでmainを眠らせておく

}

結果は以下の通りになりました。

2022/03/18 12:56:45 recv: 4  start
2022/03/18 12:56:45 recv: 1  start
2022/03/18 12:56:45 recv: 0  start
2022/03/18 12:56:45 recv: 2  start
2022/03/18 12:56:46 recv: 2 hello, world: 0 from 999
2022/03/18 12:56:46 recv: 2 hello, world: 0 from 111
2022/03/18 12:56:46 recv: 5  start
2022/03/18 12:56:46 recv: 5 hello, world: 0 from 111
2022/03/18 12:56:46 recv: 0 hello, world: 0 from 111
2022/03/18 12:56:46 recv: 4 hello, world: 0 from 111
2022/03/18 12:56:46 recv: 1 hello, world: 0 from 111
2022/03/18 12:56:47 recv: 1 hello, world: 1 from 111
2022/03/18 12:56:47 recv: 4 hello, world: 1 from 999
2022/03/18 12:56:47 recv: 1 hello, world: 1 from 999
2022/03/18 12:56:47 recv: 2 hello, world: 1 from 999
2022/03/18 12:56:47 recv: 0 hello, world: 1 from 999
2022/03/18 12:56:47 recv: 5 hello, world: 1 from 111
2022/03/18 12:56:47 recv: 5 hello, world: 1 from 999
2022/03/18 12:56:48 recv: 1 hello, world: 2 from 999
2022/03/18 12:56:48 recv: 5 hello, world: 2 from 999
2022/03/18 12:56:48 recv: 2 hello, world: 2 from 999
2022/03/18 12:56:48 recv: 0 hello, world: 2 from 999
2022/03/18 12:56:48 recv: 4 hello, world: 2 from 999
2022/03/18 12:56:49 recv: 4 hello, world: 3 from 999
2022/03/18 12:56:49 recv: 1 hello, world: 3 from 999
2022/03/18 12:56:49 recv: 5 hello, world: 3 from 999
2022/03/18 12:56:49 recv: 2 hello, world: 3 from 999
2022/03/18 12:56:49 recv: 0 hello, world: 3 from 999
2022/03/18 12:56:49 recv: 0 hello, world: 3 from 111
2022/03/18 12:56:49 recv: 1 hello, world: 3 from 111
2022/03/18 12:56:49 recv: 4 hello, world: 3 from 111
2022/03/18 12:56:49 recv: 5 hello, world: 3 from 111
2022/03/18 12:56:49 recv: 5  stop
2022/03/18 12:56:49 recv: 2 hello, world: 3 from 111
2022/03/18 12:56:49 recv: 1  stop
2022/03/18 12:56:50 recv: 2 hello, world: 4 from 111
2022/03/18 12:56:50 recv: 2 hello, world: 4 from 999
2022/03/18 12:56:50 recv: 0 hello, world: 4 from 111
2022/03/18 12:56:50 recv: 0 hello, world: 4 from 999
2022/03/18 12:56:50 recv: 4 hello, world: 4 from 999
2022/03/18 12:56:51 recv: 4 hello, world: 5 from 999
2022/03/18 12:56:51 recv: 4 hello, world: 5 from 111
2022/03/18 12:56:51 recv: 2 hello, world: 5 from 111
2022/03/18 12:56:51 recv: 0 hello, world: 5 from 111
2022/03/18 12:56:52 recv: 0 hello, world: 6 from 999
2022/03/18 12:56:52 recv: 0 hello, world: 6 from 111
2022/03/18 12:56:52 recv: 4 hello, world: 6 from 111
2022/03/18 12:56:52 recv: 2 hello, world: 6 from 111
2022/03/18 12:56:53 recv: 2 hello, world: 7 from 111
2022/03/18 12:56:53 recv: 2 hello, world: 7 from 999
2022/03/18 12:56:53 recv: 0 hello, world: 7 from 999
2022/03/18 12:56:53 recv: 4 hello, world: 7 from 999
2022/03/18 12:56:54 recv: 4 hello, world: 8 from 111
2022/03/18 12:56:54 recv: 4 hello, world: 8 from 999
2022/03/18 12:56:54 recv: 4  stop
2022/03/18 12:56:54 recv: 2 hello, world: 8 from 111
2022/03/18 12:56:54 recv: 2 hello, world: 8 from 999
2022/03/18 12:56:54 recv: 2  stop
2022/03/18 12:56:54 recv: 0 hello, world: 8 from 111
2022/03/18 12:56:54 recv: 0  stop

ちょっと見難いので、"recv: 2"を、それぞれ異なる送信者ごとに整理してみます。

c:\Users\ebata\goga\1-7\test>grep "recv: 2" dummy.txt | grep 999
grep "recv: 2" dummy.txt | grep 111
2022/03/18 12:56:46 recv: 2 hello, world: 0 from 111
2022/03/18 12:56:49 recv: 2 hello, world: 3 from 111
2022/03/18 12:56:50 recv: 2 hello, world: 4 from 111
2022/03/18 12:56:51 recv: 2 hello, world: 5 from 111
2022/03/18 12:56:52 recv: 2 hello, world: 6 from 111
2022/03/18 12:56:53 recv: 2 hello, world: 7 from 111
2022/03/18 12:56:54 recv: 2 hello, world: 8 from 111

2番がロストしています。

c:\Users\ebata\goga\1-7\test>grep "recv: 2" dummy.txt | grep 999
grep "recv: 2" dummy.txt | grep 999
2022/03/18 12:56:46 recv: 2 hello, world: 0 from 999
2022/03/18 12:56:47 recv: 2 hello, world: 1 from 999
2022/03/18 12:56:48 recv: 2 hello, world: 2 from 999
2022/03/18 12:56:49 recv: 2 hello, world: 3 from 999
2022/03/18 12:56:50 recv: 2 hello, world: 4 from 999
2022/03/18 12:56:53 recv: 2 hello, world: 7 from 999
2022/03/18 12:56:54 recv: 2 hello, world: 8 from 999

5、6番がロストしています。


送信者を1人にすれば、問題が発生する可能性はなくなる」という仮説は成り立ちそうです。

考えてみれば、このプログラムでは、2つの送信者を区別する方法を入れていないのですから、当然かもしれません。

という訳で、送信者を1人にする方法の実装で、もうちょっとがんばってみたいと思います。

ただ、この方式では、送受信の際にロックをかけているので、受信者の数が膨大になれば、プログラム全体のパフォーマンスが劣化する可能性があります。

リアルタイム系のプログラムには、使わない方が良いかもしれません。

ただ、プログラムの動作状況を簡単に見たいようなケースでは、とても便利なので、当面は手放せないと思います。

以上

 

 

 

 

 

2022/03,江端さんの技術メモ

Go の channel 処理パターン集

func main() {
	ii := 10

	queue := make(chan int, 100)
	defer close(queue)

	for i := 0; i < 5; i++ {
		go worker(i, queue)
	}

	for {
		//k := rand.Intn(1000)

		for i := 0; i < 200; i++ {
			queue <- ii
		}

		time.Sleep(1 * time.Second) // 2秒待つ

		ii++
		go worker(ii, queue)

	}

}

func worker(i int, queue chan int) {
	for j := range queue {
		fmt.Println(i, ",", j)
	}
}

2022/03,江端さんの技術メモ

Goの複数のgoroutineに対して、一斉ブロードキャストを行いたい

を教えて貰って、喜んでいたのですが、私のようなカルトな使い方をしているケースでは、正しくデータ送信ができない場合があるようです。

動的に登場して、自動的に消滅するような複数の(かなりの数の)goroutineに対しては、受信データの値が変な値になるようです。

下記は、データ送信元のオブジェクトが、自分の位置情報を撒き散らしながらbroadcast送信をしています。

下記は、この途中からgoroutineをバラバラに30個くらい作って受信したものの一つです。

なんども調べてみたのですが、やはりバグが原因ではないようです。

本日、バグを発見しました! 構造体に送信元のオブジェクトを指定する変数が入っていなかった為、全部同じブロードキャストとして受信先が受信をしてしまっていました(03/18)。

ここから得られる結論は、Sync.Cond、broadcastを使うには、

・broadcast、sync.cond は、最初からgoroutineができあがっている場合

・少量、低速にデータ配信を行う場合

でないと、安定的に動作させるには厳しいようです。

これは、まあ、間違ってはいませんです。

====  追記 =====

そういえば、ブロードキャストの送信者が1であった場合は問題がなかったけど、今回は、送信者が3になったところから、変な動きをしだしたことから鑑みて、

送信者、受信者は1:Nの関係でないとだめ

なのかもしれないです。

これは確定です。詳しくは以下をご覧下さい↓

Goの複数のgoroutineに対する一斉ブロードキャストを、まだ諦めきれない

以上

2022/03,江端さんの忘備録

ウクライナ支援が、私の人生では見たことのないペースで世界に広がっています。

Ukrainian aid is spreading around the world at a pace I have never seen in my life.

支援に関しては、

As for the aid,

―― 御託(ごたく)はいいんだよ! 金出せ、コノヤロー!!(泉谷しげるさん風)

"You don't care what someone says! Give me the money, motherfucker! (Shigeru Izumitani style)

のスタンスで、全然O.K.だと思っています。

I think this stance is totally O.K.

例え、メディアやSNSによる情宣に影響されていたとしても ――

Even if we are influenced by media and social networking propaganda --

ある国の国内で子どもが殺されている映像があって、

There was a video of a child being killed within the borders of a country.

他方の国の国内で子どもが殺されている映像がなければ、

Unless there are images of children being killed on the other country's soil.

私は「思考停止」していい、と思っています。

I am willing to "stop thinking".

子どもが殺されている国を支援するのに、これ以上の理由は必要ありません。

No better reason is needed to support a country where children are being killed.

-----

私は、この自分の感情に従いたいのですが、ある(他の人から見ればどうでもいい)ことに拘っています。

I want to follow this feeling of mine, but I am concerned about certain (unimportant to others) things.

アフガニスタン、ミャンマー、チベット、ウイグル ―― 私は、何もしてこなかったなぁ、と。

Afghanistan, Myanmar, Tibet, Uyghur -- I have done nothing.

この、形容しがたい「後ろめたさ」が、私が動くのを躊躇させています。

This formidable "guilt" is holding me back from making me move.

なにか「個人的理由」に関わるものでもあれば、私は簡単に「発火」するんだけどなー

If something was about "personal reasons", I'd "fire" easily...

-----

今、私は、せっせとGISソフトウェアの開発をしているのですが、昨夜、APIの使い方が分からなくて、前提となるOSS(leaflet)を調べていました。

PrumeMobileを使ってみた結果(1st_trialとadp_test)

I'm working hard on GIS software right now, and last night I was looking up the prerequisite OSS (leaflet) because I couldn't figure out how to use the API.

そこで、このページに辿りつきました。

That is how I came across this page.

そして、そこに書かれているフレーズに目が引付けられました。

And the phrase written there caught my attention.

"If an appeal to humanity doesn't work for you, I'll appeal to your egoism: the future of Ukrainian citizens is the future of Leaflet."

(もし、あなたの人道主義に訴えないのであれば、私は、あなたの利己主義に訴えます:ウクライナ市民の未来は、Leafletの未来です)

-----

よくぞ言ってくれた! そう言って欲しかった!!

Well said! I wish you would have said so!!!!

このフレーズで、私の「利己主義」に"火"が付きました。

This phrase ignited my "selfishness".

私は、人道的ではなく、あくまで利己的に、Leafletを守るため「だけ」に、ウクライナを圧倒的かつ絶対的に支援します。

I support Ukraine overwhelmingly and absolutely, not humanely, but only selfishly, "only" to save Leaflet.

ウクライナを守ることは、私のリタイア後の生きる術(GISソフトウェア開発)を死守することと同義です。

Defending Ukraine is synonymous with defending my retirement way of life (GIS software development) to the death.

『Leafletの開発者に、避難先からキエフに戻ってもらって、これからも、Leaflet開発に励んで頂く』

"I am asking the developers of Leaflet to return to Kiev from their evacuation site and continue to work hard on Leaflet development"

私の「ウクライナの支援」の理由としては、これで十分です。

This is sufficient reason for my "support of Ukraine".

未分類

=6371 * ACOS(COS(A2*PI()/180) * COS(A3*PI()/180) * COS(B3*PI()/180-B2*PI()/180) + SIN(A2*PI()/180) * SIN(A3*PI()/180) )

参考文献 緯度経度から2地点間の距離を計算する!Google方式とヒュベニ式・表計算ソフトで計算できる・GPSデータも使える

こちらがエクセル表のサンプル → Book1.xlsx

2022/03,江端さんの忘備録

昨日、確定申告の締切日(?)でしたが、e-Taxシステム(国税電子申告・納税システム)にシステム障害が発生していて、騒ぎになっています。

Yesterday was the deadline for filing tax returns, but there was a system failure in the e-Tax system (National Tax Electronic Filing and Payment System), which caused a commotion.

ちなみに、私は、一週間前に提出を終えて、セーフでしたが。

Since I finished the submission a week ago, I was O.K.

原因は不明とのことですが、私は『締切日前の負荷集中が原因だろう』と思っています。

The cause is unknown, but I believe it is 'probably due to the concentration of load before the deadline'.

-----

多くの人は、「サイバー攻撃」がとても高度な技術と思っているかもしれませんが、基本的には、今回の、e-Taxシステムのシステム障害と同じことを、人為的にやっているだけです。

Many people may think that a "cyber attack" is a very sophisticated technology, but it is basically just an artificial attempt to do the same thing as the recent system failure of the e-Tax system.

サーバに対して、怒涛のようなアクセスを仕掛ければ、どんなサーバでも(基本的には)ダウンします。

Any server will (basically) go down if you set up a raging access against it.

若い頃に、私はスパムメールの発信元のサーバに対して、コンピュータに自動生成した膨大な数の抗議のメールを、サーバに返信させ続けたことがあります(時効成立済み)。

When I was younger, I used to keep sending a huge number of computer-generated protest e-mails to the servers of spammers (statute of limitations has expired).

その後、そのサーバはアクセスできない状態になりました。

The server was then inaccessible.

もっとも、これは「サーバをダウンさせるだけ」の攻撃であり、「乗っ取りする」とか「コンテンツを書き換える」などの攻撃には、もう数段の高度な技が必要になります。

However, this is an attack that "only brings down the server." In order to "hijack" or "rewrite content," a more advanced technique is required.

ドメイン名を持っているサーバ(インターネットで公開されているサーバ)は、そのサーバ立ち上げの瞬間から、クラッキングされます。

A server that has a domain name (a server that is publicly available on the Internet) can be cracked from the moment it is launched.

私のサーバ(kobore.net)も例外ではありません。

My server (kobore.net) is no exception.

-----

ロシア政府のWebサーバへのアクセスができなくなるという状況が、発生したと聞いています。

I have heard that the Russian government's web server was inaccessible.

そして、私も、現在、ロシアかウクライナにある(と推定されている)サーバのサービスが受けられなくなっています。

And I, too, am currently unable to get service on a server that is (presumably) in Russia or Ukraine.

今や、我が国のサーバも、サイバー攻撃の標的になっていることは確実です。

It is certain that our nation's servers are now the target of cyber attacks.

『私はサーバの運用などやっていないから大丈夫』と思っている人が多いかもしれませんが、「サーバ攻撃に加担させらている」可能性はあります。

Many people may think, "I don't run servers, so I don't have to worry about it," but there is a possibility that they are being forced to participate in server attacks.

サーバをダウンさせるためには、怒涛のようなアクセスを仕掛ける必要があるのですが、例えば、1000台のPCを乗っ取ることができれば、1000台からのサイバー攻撃が可能となります。

In order to bring down a server system, it is necessary to plant a raging access. For example, if 1,000 PCs can be hijacked, the cyber attack can be launched from 1,000 PCs.

「自分のパソコンを乗っ取られて、自国のインフラシステムを攻撃する兵器」にしない為にも、少なくとも、定期的に"Windows Update"くらいはしておきましょう。

To prevent your computer from being hijacked and used as a weapon to attack your country's infrastructure, you should at least perform "Windows Update" regularly.

-----

よい機会です ―― ここは一つ、「サイバー攻撃教育」を、真面目に検討してみませんか?

This is a good opportunity -- why don't we take a serious look at "cyber attack education"?

2022/03,江端さんの技術メモ

1. サーバの方の改造
(a) POPUP int `json:"popup"` の追加

// GetLoc GetLoc
type GetLoc struct {
	ID    int     `json:"id"`
	Lat   float64 `json:"lat"`
	Lng   float64 `json:"lng"`
	TYPE  string  `json:"type"` // "PERSON","BUS","CONTROL
	POPUP int     `json:"popup"`
	//Address string  `json:"address"`
}

(b) javascriptに、this.popup = popup;を追加

function obj(id, lat, lng, type, popup){
	this.id = id;
	this.lat = lat;
	this.lng = lng;
	this.type = type;
	this.popup = popup;
}

(c) javascriptに、

var i = obj.popup;

popup: "Person " + i,

を追加

var i = obj.popup;

		if (obj.id == 0) {
			if (obj.type == "PERSON"){
				var marker = new PruneCluster.Marker(obj.lat, obj.lng, {
					popup: "Person " + i,
					icon: L.icon({
						iconUrl: 'http://localhost:8080/static/person-icon.png', 
					})
				});
			}
			else if (obj.type == "BUS"){
				var marker = new PruneCluster.Marker(obj.lat, obj.lng, {
					popup: "Bus " + i,
					icon: L.icon({
						iconUrl: 'http://localhost:8080/static/bus-icon.png', 
					})
				});

			}

2. クライアントの方の改造

(1)以下はサーバと同じ
// GetLoc GetLoc
type GetLoc struct {
	ID    int     `json:"id"`
	Lat   float64 `json:"lat"`
	Lng   float64 `json:"lng"`
	TYPE  string  `json:"type"` // "USER","BUS","CONTROL
	POPUP int     `json:"popup"`
	//Address string  `json:"address"`
}
gl := ldarp.GetLoc{
		ID: 0, // "0"としなければならない
		//	Lat:  35.64553503, // 初期の場所
		//	Lng:  139.78468208,
		TYPE: "PERSON", // "PERSON","BUS","CENTER"のいずれかが選べる
	}

	// glの要素を外出し
	gl.Lat = person.Destination.Lat
	gl.Lng = person.Destination.Lon
	gl.POPUP = person_num

keyword ポップアップ PruneMobile PruneCluster  Golang JavaScript

2022/03,江端さんの忘備録

私が法学ゼミに通っていた頃、講師に教えて貰った言葉に、

When I was a student at a law seminar, my instructor taught me the following phrase.

―― 「憲法違反」と言い出した弁護士は、裁判官に対して「敗北宣言」をしている

"Lawyers who say "violation of the Constitution" are "declaring defeat" to the judge"

がありました。

裁判とは、基本的には民法や刑法などの、具体的な法律の条文を持ちいて、被告の行った行為に適用できるか否かを争うバトルです。

"Judge" is basically a battle to determine whether or not a specific article of law, such as the Civil Code or the Criminal Code, can be applied to the defendant's conduct.

つまり「被告の行った行為と、一般法の条文とのマッチング」です。

In other words, "matching the defendant's conduct with the text of the general law.

「憲法」は、法律の最高法規でありますが、基本的には「コンセプト(概念とか理念)」です。

The "Constitution" is the supreme law of the land, but it is basically a "concept" (or idea).

「憲法」を持ち出して判決をすること自体が、かなりのレアケースです。

Bringing up the "Constitution" to make a ruling is in itself a pretty rare case.

レアケースである理由は、その事件の内容が、この国の司法のみならず社会全体に与える影響がハンパではないからです。

The reason why it is a rare case is because the impact of the case on not only the judiciary of this country, but also on society as a whole, is not humbling.

それゆえ、憲法違反を理由とする裁判の判決は、重大なニュースソースになるのです。

Hence, a court ruling on a constitutional violation is a significant news source.

同性婚や、最近の優性保護法による除斥期間に関する判決は、一般法とのマッチングでは、判断できない重要な案件だったのです。

Same-sex marriage and the recent ruling on the exclusionary period under the Superiority Protection Act were important cases that could not be decided by matching them with the general law.

-----

このような感じで言うと、

Let me put it this way, I can say,

―― 「核兵器の使用」を言い出した国家元首は、戦争に対して「敗北宣言」をしている

"Any head of state who says "use nuclear weapons" is "declaring defeat" for the war"

とも言えます。

ただ、核兵器の使用権(いわゆる「核のボタン」)は、その国の統治者に一任されていますので、結局のところ

However, the right to use nuclear weapons (the so-called "nuclear button") is left entirely up to the ruler of the country, so in the end

『私が死んだ後の世界がどうなろうが、知ったことか』

"I don't care what happens to the world after I die"

と開き直った統治者だけが、「世界でたった一人の勝利者」となる、ということになります。

Thus, only the ruler who become defiant will be the "one and only winner in the world," and so on.

-----

実際に、私が知っているだけでも、過去、システムエラーで"4回"核戦争の危機がありましたが、現場の判断で回避されました。

In fact, as far as I know, there have been "four times" in the past when nuclear war was threatened due to system errors, but the situation was averted due to on-site decisions.

しかし、人間のエラー(開き直った統治者)を、システムが止める ―― そういう逆転現象は、あまり期待できないと思います。

However, I don't think we can expect such a reversal -- like, the system stops a human error (defiant ruler).

2022/03,江端さんの技術メモ

参考文献  【レッツカスタマイズ】Visual Code StudioにGo言語の開発環境を整えてみよう!

1. Goの開発環境をインストール

2. setting.jsonにgopathを書き込む

Windowsの場合は、"C:\go"は、"C:\\go"と書かないと動かない(みたい)

3. (Ctr+Shift+P)でショートカットで検索バーを表示し、「GO: Install/Update tools」を入力してヒットしたメニューをクリック

全部選んで、インストールする

4. VSCodeを離れて、コマンドプロンプトから、以下のコマンドを実行する

$ go get -u -v github.com/go-delve/delve/cmd/dlv

5. launch.jsonに以下のように書き込む

{
    // IntelliSense を使用して利用可能な属性を学べます。
    // 既存の属性の説明をホバーして表示します。
    // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch",
            "type": "go",
            "request": "launch",
            "mode": "auto",
            "program": "${fileDirname}",
            "env": {},
            "args": []
        }
    ]
}

これで、

GO_1_could not launch process: not an executable file_CC课堂-CSDN博客

加えて、(バカみたいな感じもするが)ライブラリのコードでブレークする場合であっても、main.goのウインドウの方をアクティブにしておかなければならないみたい

これで、エラーは出てこなくなる(みたい)。

 

2022/03,江端さんの忘備録

私は、見たくないものからは、目を背けるようにしています。

I try to turn away from things I don't want to see.

見たくないものを見るのは、「辛い」ことだからです。

It is "hard" to see what I don't want to see.

ですので、私は、見たいものだけを見て、都合よくそれらとだけ、付き合うことにしています。

So I will only see what I want to see, and only follow them, conveniently.

これを「卑怯」ということはできますが、

You can call this "cowardly," but

―― SNSで通り一遍の批判をするだけで、立ち去るやつらと、大して変わらん

"I'm not much different from the guys on social media who just make passing criticisms and walk away."

と分かってからは、この「卑怯」を公言するようになりました。

I began to profess this "cowardice" after I found out that

-----

現在、私は、目を逸らし続けている事項が沢山ありますが、その中の一つに「子どもへの虐待」があります。

Currently, there are many matters that I continue to turn a blind eye to, one of which is 'abuse of children'.

この問題、

This problem is the ultimate evil, like,

―― 無限暴力装置(虐待する親)を設置した密室(自宅)に、子どもを放置し続ける

"Continuing to leave children in a closed room (home) with an endless violent device (abusive parent)"

という、究極の悪です。

しかし、多くの人が奮闘努力しているのにも関わらず、これを解決する決定的な方法が見つかっていません。

However, despite the efforts of many people struggling to find a solution, no definitive method has been found to solve this problem.

『子どもが親に殺される続ける現状に、何もできない』という現実を、真正面から見ることは、本当に『辛い』ことです。

It is really 'painful' to see head-on the reality that 'nothing can be done about the current situation where children keep getting killed by their parents'.

ですので、私は、この問題から目を逸らし続けてきました。

So I have continued to turn a blind eye to this problem.

 

-----

先日、コラムの編集作業をしながら、NetFlixで「コタローは1人暮らし」というアニメの第1話を見て、その後、これを一気に全話見てしまいました。

The other day, while editing my column, I watched the first episode of an anime called "Kotaro Lives Alone" on NetFlix, and then watched all the episodes of this one at once!

過激な描写やストーリが一切登場してこない、楽しいアニメでしたが、

It was an enjoyable animation, though, with no extreme depictions or storied scenes appearing.

―― この問題から逃げ続けてきた私には、視聴後に、地味に、じわじわと、そのツケが回ってくるような

I have been running away from this issue, and it seems to me that the bill for it was coming soberly, slowly after watching this anime.

作品でした。

ともあれ、コメディ風に描かれている絵もストーリーもとても愉快ですから、身構えることもなく、普通に作品を楽しんで貰いたいです。

Anyway, both the pictures and the story, which are drawn in a comedic style, are very funny, so I hope that you will enjoy the work in a normal way without getting defensive.

-----

私も ―― 「コタローは1人暮らし」のような、

I hope to deliver such works (columns, etc.) to many people, like "Kotaro lives alone",

『世間の人々が、そのままでは食べにくい食べ物(生野菜)を、上手く調理して、食べやすい食事として提供する』

"The food (raw vegetables), which is difficult for people to eat as it is, is prepared well and served as an easy-to-eat meal"

というような作品(コラム等)を、多くの人に届けられたらいいなぁ、と思っています。