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

ロシアのウクライナ侵攻前から、私は「テレ東BIZ」をウォッチし続けています。

I have been watching "TV Tokyo BIZ" since before the Russian invasion of Ukraine.

「この番組はいいな」と思っています。

I like this program.

解説者が、丹念に勉強して、調べているように見えるからです。

This is because the commentator appears to have studied and researched the subject with great care.

私、解説者が「専門家」である必要はないと思っています。

I do not believe that commentators need necessarily be "experts".

むしろ、その分野の素人が、最新のニュースソースと定量的な数値(歴史も含む)を用いて、そこから導いた仮説(地味な仮説)の方が、私には役に立ちます。

Rather, I find it more useful to have a hypothesis (a humble hypothesis) derived from it by a person outside the field, using up-to-date news sources and quantitative figures (including history).

-----

専門家、論者、有識者といわれる皆さん ―― 『うるさい』

To all the so-called experts, commentators, and pundits -- "Shut up.

あなたたちの「悲しい」やら「酷い」やら「正義」やら、そんなものを持ち込まないで下さい。

Please don't bring your "sad" or "terrible" or "righteous" or whatever into me.

私は、あなたがたの願望(理念、理想)を混入させたコメントなんぞに、1mmも興味ありません。

I am not interested in a single millimeter of your comments laced with your desires (ideals, ideals).

私がニュース解説に求めているものは、「数字を用いて説明される事項」であり、そして、その事実から導かれる客観的な「見解」です。

What I look for in a news commentary is "matters explained with figures" and an objective "view" derived from those facts.

水が低いところに流れていくように、普通に考えれば、普通に導かれる、普通の予測です。

It is a normal forecast, normally guided by normal thinking, just as water flows to a lower place.

-----

「テレ東BIZ」では、戦争開始前に、

In "TV Tokyo BIZ," before the war began, the following commentary was given

『ウクライナ侵攻は、客観的な情報を纏めると"ない"と考えるのが普通』

"Based on objective information, it is common to assume that there will be no invasion of Ukraine.

『なぜなら、ウクライナ全土を実効支配し続けるのは、兵力や財力の観点から無理があるから』

"Because it is impossible to maintain effective control over the whole of Ukraine in terms of troops and financial resources.

『それでも、歴史上の戦争は、概ね、予想外のことで始まっている。今回も何が起こるか分からない』

"Still, wars throughout history have generally started with the unexpected. We don't know what will happen this time either."

と解説しており、今、まさに、その予測通りのことが起こっています。

Right now, that is exactly what the program predicted would happen.

「テレ東BIZ」で用いた数値は、人員、武装の種類と数、ウクライナ国土の面積と、戦争継続に必要な経費くらいの、ラフなものでしてが、私には非常に肚に落ちました。

The figures used in "TV Tokyo BIZ" were very rough, about the number and type of personnel and armaments, the area of Ukraine, and the expenses required to continue the war, but they were very clear to me.

専門家、論者、有識者といわれる皆さん。

To all of you who are called experts, orators, or intellectuals.

この戦争を語るなら、まず、この程度の数値がスラスラと出てくるくらいは勉強をしてから、論じて下さい。

If you are going to talk about this war, please first study enough to be able to slur these figures before discussing them.

-----

例えば、現在のウクライナの人口は4400万人です。

For example, Ukraine's current population is 44 million.

そして、現在、200万人強が国外への避難をしています。

And just over 2 million people have now fled the country.

つまり、脱出できている人数は、わずか5%弱です。

In other words, only less than 5% of the population is able to escape.

国民の大半は国外に脱出できていません。

he majority of the population has not been able to leave the country.

ポーランドの人口は4000万人、ルーマニアの人口は2000万人、スロバキアの人口は500万人、モルドバなんて、300万人弱です。

Poland has a population of 40 million, Romania 20 million, Slovakia 5 million, and Moldova less than 3 million.

ここに、ウクライナの人口の半分、2000万人が逃げこむことができるか? ―― できるわけがない。

Can 20 million people, half of Ukraine's population, flee here? -- It can't be done.

そして、国内に残っている4000万人の反ロシア感情(一部、親ロシア派もいる)で一致する国民を、ロシアは実効支配できるか? ―― かなり難しいだろう。

And can Russia effectively control the 40 million people remaining in the country who are united in their anti-Russian (and some pro-Russian) sentiments? -- It will be very difficult.

出典: 北大西洋条約機構(NATO)について(https://www.mofa.go.jp/mofaj/files/100156880.pdf)

「テレ東BIZ」の解説は、こんな感じです(上記の数値は、私が今、5分間で調べました)。

Here's how "TV Tokyo BIZ" describes it (I just spent 5 minutes looking up the numbers above).

という訳で、ウクライナ侵攻に関するニュースについては、私は、"NHK"と"テレ東BIZ"だけで把握しています。

Therefore, I keep track of the news regarding the invasion of Ukraine only on "NHK" and "TV Tokyo BIZ".

未分類

詳しくは、1-9/readme.md 参照のこと

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

今回の「ウクライナ侵攻」と、(私から見て)ほぼ同じ理由と同じ条件で行われた侵攻があります。

There is this "invasion of Ukraine" and an invasion that (from my point of view) was carried out for almost the same reasons and under the same conditions.

ソビエト連邦軍主導(今のロシア)のワルシャワ条約機構軍による軍事介入(1968)の「チェコ事件」です。

The "Czech Incident" was a military intervention (1968) by Soviet Union-led (now Russian) Warsaw Pact Organization forces.

「プラハの春」「ブレジネフ・ドクトリン」で覚えている人が多いかもしれません。

You may remember them from "Prague Spring" and "The Brezhnev Doctrine."

(ちなみに、江端は「ドクトリン」という言葉を濫用する傾向がありますが、この(ブレジネフ・ドクトリン)からの引用です)

(Incidentally, Ebata tends to abuse the term "doctrine," but he is quoting from this (Brezhnev Doctrine).

-----

「プラハの春」とは、社会主義国家であるチェコスロバキアが、社会主義体制の中で「人間の顔をした社会主義」というスローガンの元に、

The "Prague Spring" was the following activities of Czechoslovakia, a socialist state, under the slogan "socialism with a human face" within the socialist system.

(1)共産党へ一党支配からの脱却

(1) Breaking away from one-party rule to the Communist Party

(2)企業責任の拡大や市場機能の導入など、資本主義の経済改革

(2) Economic reforms of capitalism, such as the expansion of corporate responsibility and the introduction of market functions

(3)言論や芸術活動の自由化

(3) Liberalization of speech and artistic activities

(4)科学技術の導入を通した西側との経済関係の強化

(4) Strengthen economic ties with the West through the introduction of science and technology

を掲げた運動を言い、

「チェコ事件」とは、ワルシャワ条約機構軍(実質的にはソ連軍)が、この活動(プラハの春)を武力弾圧して、現政権を倒して、ソ連よりの(傀儡)政権を打ち立てた事件です。

The "Czech Incident" was an incident in which Warsaw Pact forces (in effect, Soviet forces) suppressed this activity by force, toppling the current government and establishing a more Soviet (puppet) government.

-----

私、この「チェコ事件」の軍事介入から武力制圧までの時間を調べてみたのですが、

I, looked up the time between the military intervention and the armed suppression of this "Czech Incident"

―― たったの2日間

It was "Only two days"

でした。

この時、市民は抗戦しません(できません)でしたし、西側も「ブレジネフ・ドクトリン」を、事実上、黙認しました。

At this time, the public did not fight back, and the West effectively tacitly endorsed the "Brezhnev Doctrine.

-----

で、まあ、そういうことを知っている私は ―― 正直に言いますが、

And, well, I know that kind of thing -- I'm going to be honest with you.

『今回のウクライナ侵攻は、4日間で、ロシアの制圧で終了する』と思っていました。

I thought, 'This invasion of Ukraine will end in four days, with Russia in control'

加えて、『その後、ロシアは、ウクライナ国内のゲリラ活動に、散々苦しめられた後、20年後に撤収することになる』という、アフガニスタン侵攻のパターンを想定していました(これは、米国のベトナム戦争とも同じ)

In addition, the pattern of the invasion of Afghanistan was assumed: "After that, Russia will be forced to withdraw after 20 years, after being tormented by guerrilla activities in Ukraine" (this is the same as the US Vietnam War).

だから、今、本当にビックリしています。

So now I am really surprised.

―― 20世紀から現在に至るまでの、列強支配のパラダイムやメソッドは、もはや当てはまらなくなっているのかも

"The paradigms and methods of power domination from the 20th century to the present may no longer apply"

と、実感しています。

I realize that.

-----

で、ウクライナ支援ですが、私の調べた感じでは、こちらは、詐欺サイトなどではないようです。

So, Ukraine Support, from what I have been able to find out, this is not a scam site or anything like that.

日本語のページもあります。

There is also a page in Japanese.

私は、上記のサイトからの各種の支援を考えています。

I am considering various types of assistance from the above mentioned sites.

ここから、ボランティアの登録もできます。

You can also register as a volunteer here.

"IT Product Management"でエントリー登録しても、『ロシアへのサイバー攻撃に参加してくれ』と言われることはないだろうとは、思っていますけど。

"I don't think if I register for an entry in IT Product Management, I will be asked to 'participate in a cyber attack on Russia'.

国内法で裁かれるかどうかは、条文読んでみないと分かりません。

I am not sure whether I will be tried under domestic laws.

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