2023,江端さんの技術メモ

"github.com/gorilla/websocket"の有名なバグ(らしい)

■PruneMobile側(sever.go)

■gtfs_hub側(gtfs_hub.go)

■対策

[Go言語/JavaScript]WebSocketsでチャットアプリを実装!~ユーザーリスト表示編~


PruneMobile側(sever.go)の方が先に落ちる(確認) → で書き込みできなくなってgtfs_hub側(gtfs_hub.go)も落ちる、と、多分、そんな感じ。

"repeated read on failed websocket connection"を普通に読めば、「間違ったWebsocket接続で、*何度*も読み込みを繰り返している」なので、read errorが発生したら、即コネクションクローズして、クライアントも落してしまえばいいのかな、と考えました。→ ダメでした。サーバが落ちて処理が止まります。

で、以前、

Golangのサーバなんか大嫌い

で、

"http.HandleFunc()"は、クライアントがやってくるごにに一つづつ立ち上があるfork()のようなものである

てなことを書いていたので、read errorqを検知したら、forループから直ちにbreakして、クライアントをクラッシュさせてしまうこと(ができるものと)しました。→ ダメでした。サーバが落ちて処理が止まります。

 

for (){
      (色々)
           err = webConn.ReadJSON(&locMsg2) // ここでPanic serving  ... repeated read on failed websocket connectionが発生している可能性あり
           fmt.Printf("c6: ")
           if err != nil{
              fmt.Printf("Before webConn.close(), After c6:")
               webConn.Close()
               break → ダメ
           }
}

javascript (onload.js) の方にも、終了理由がでるように、以下のコードを追加しました。

// サーバを止めると、ここに飛んでくる
  socket.onclose = function (event) {
      console.log("socket.onclose");
  
      let obj = JSON.parse(event.data);
  
      console.log("socket.onclose: obj.id:", obj.id);
      console.log("socket.onclose: obj.lat:", obj.lat);
      console.log("socket.onclose: obj.lng:", obj.lng);
      console.log("socket.onclose: obj.type:", obj.type);
      console.log("socket.onclose: obj.popup:", obj.popup);
  
      socket = null;
  
      // 切断が完全に完了したかどうか
      if(event.wasClean){
          var closed = "完了";
      } else {
          var closed = "未完了";
      }
      info.innerHTML += "切断処理:" + closed + "<br>";
      info.innerHTML += "コード:" + event.code + "<br>";
      info.innerHTML += "理由:" + event.reason + "<br>";
  
  }
  
  window.onunload = function(event){
      // 切断
      ws.close(4500,"切断理由");
  }

上記の「ダメ」の対策中

https://ja.stackoverflow.com/questions/12389/golang%E3%81%A7%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%92%E5%86%8D%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF%E3%81%99%E3%82%8B%E3%81%A8websocket-server%E3%81%8C%E8%90%BD%E3%81%A1%E3%82%8B


■問題解決編

色々問題があったのですが、順番に説明していきます。


	var addr = flag.String("addr", "192.168.0.8:8080", "http service address") // テスト
	....
	.....
	http.Handle("/", http.FileServer(http.Dir(".")))


	http.HandleFunc("/echo", echo)                                           // echo関数を登録 (サーバとして必要)
	log.Fatal(http.ListenAndServeTLS(*addr, "./cert.pem", "./key.pem", nil)) // localhost:8080で起動をセット
}

まず第一に、http.HandleFunc()の誤解がありました。私は、これを、fork()のようにプロセスかスレッドを発生さるものと思っていましたが、これは、一言で言えば、単なるコールバック関数でした。

乱暴に言えば、Webからアクセスがあると、echo()というファンクションに吹っ飛ばされる、という現象を発生させる"だけ"で、それ意外のことは何にもしてくれないのです。

では、echo()の方はどうなっているかというと、

func echo(w http.ResponseWriter, r *http.Request) { // JavaScriptとの通信
	webConn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println("websocket connection err:", err)
		return
	}
	defer webConn.Close()

とすることで、webSocket通信の準備ができて、その通信路が"webConn"にできる、ということです。
で、それ意外のことは何もしてくれないのです。

つまり、2つのWebブラウザからアクセスがくると、その度、echo()に飛んできて、その度に、異なるwebConnを生成する、ということです。

ここまでの説明で分かると思いますが、つまり、Webブラウザがくる度に、それをどっかに格納しておかないと、通信路の情報が上書きされてしまいます

なので、基本的には、以下のwebConnを、配列に格納しておきます。

var clients = make(map[*websocket.Conn]bool) // 接続されるクライアント
という動的な配列を準備しておき、アクセスがある度に、
// クライアントを新しく登録(だけ)
    m1Mutex.Lock() // 同時書き込みを回避するため、ミューテックスロックで囲っておく
    clients[webConn] = true  // これで、Webからのアクセスがある度に、通信路情報が動的に追加される
    m1Mutex.Unlock()

というように、Webブラウザとの通信路を別々に管理しておきます。

もし、fork()みたいなことがしたいのであれば、goroutineを起動して、そのgoroutineにWebブラウザの通信路を明け渡す必要があります。それでも、通信路の全体管理は、echo()が握っているので、webConnを消滅されたい場合は、echo()の方でやって貰う必要があります。

この方法を実現する方法として、GO言語のサンプルプログラムで良く登場するのが、以下のような方法です。

// 江端のPCでは、c:\users\ebata\test20230412\main.go

package main

(中略)

func handleConnections(w http.ResponseWriter, r *http.Request) {
    // 送られてきたGETリクエストをwebsocketにアップグレード
    ws, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Fatal(err)
    }
    // 関数が終わった際に必ずwebsocketnのコネクションを閉じる
    defer ws.Close()

    // クライアントを新しく登録
    clients[ws] = true

    for {
        var msg Message
        // 新しいメッセージをJSONとして読み込みMessageオブジェクトにマッピングする
        err := ws.ReadJSON(&msg)
        if err != nil {
            log.Printf("error: %v", err)
            delete(clients, ws)
            break
        }
        // 新しく受信されたメッセージをブロードキャストチャネルに送る
        broadcast <- msg
    }
}

func handleMessages() {
    for {
        // ブロードキャストチャネルから次のメッセージを受け取る
        msg := <-broadcast
        // 現在接続しているクライアント全てにメッセージを送信する
        for client := range clients {
            err := client.WriteJSON(msg)
            if err != nil {
                log.Printf("error: %v", err)
                client.Close()
                delete(clients, client)
            }
        }
    }
}

上記の例では、 http.HandleFunc("/ws", handleConnections) で、handleConnectionsをコールバック関数にしておき、こちらにWebブラウザからのアクセスを全部任せます

でもって、ついでにWebからやってくる通信の全てを受けつけています(ReadJSON())。さらに、webブラウザが突然閉じられた場合などは、通信エラーとして検知して、それをクローズした後に、webConnの配列から取り除いています。これで、このブラウザからの通信路は閉じらて、消されます。

で、この通信の内容を、チャネルを使って、go handleMessagerで作った、fork()みたいなgoroutineに流し込んでいます。

結論として、fork()みたなことがやりたければ、「自力で作れ」ということになります


しかし、WebSocket単位で別々のgoroutine作るのも面倒くさいです。それに、もしそのようなgoroutineを作ったとすれば、ブロードキャストを実現しなければなりませんが、チャネルには、ブロードキャスト機能がありません(どうしても使わなければならない時は、私はredisを使っています)。

ですので、私、チャネルの配列を作って疑似的なブロードキャストを実現しようとしたのですが、このサンプルプログラムが見るからなくて、困っていました。

『echo()関数の中で、全てのWebコネクションを相手にできないかな』と考え始めました。

基本形はこんな形

for {
     message <- channel // 外部から送られてきたデータ
     for client := range clients{ //clientsはWebConnのリスト
           client.WriteJSON(message)
           client.ReadJSON(message2}
     }
}

問題は、Webブラウザは終了処理などなどをせずに、閉じられてしまうことにあります(私たちが普通にやっていることです)。

とすれば、echo()の中でコネクションの切断を検知して、それをWebConnのリスト から取り除く必要があります。

で、こんなことやってみたんですよ。

for {
     message <- channel // 外部から送られてきたデータ
     for client := range clients{ //clientsはWebConnのリスト
           err = client.WriteJSON(message)
           if err != nil{
               client.Close()
               delete(client, clients)
           err =  client.ReadJSON(message2}
           if err != nil{
               client.Close()
               delete(client, clients)
     }
}

これでは、for ルーチンの中で、回している変数を減らすという処理が不味かったようで、この場合、 echo()が終了してしまうようでした。当然、repeated.....も含めて、エラーの嵐になりました。

なので、こんな風に変更しました。


var delete_client *websocket.Comm
for {
     delete_client = nil
     message <- channel // 外部から送られてきたデータ
     for client := range clients{ //clientsはWebConnのリスト
           err = client.WriteJSON(message)
           if err != nil{
               delete_client = client
           }
           err =  client.ReadJSON(message2}
           if err != nil{
               delete_client = client
           }
     }
     if delete_client != nil{
        delete_client.Close()
        delete(clients, delete_client)
}

つまり、ループの外でコネクション処理を行う、ということです。
ただ、この方法では、ループを回っている途中に2つ以上のWebブラウザが落された場合にどうなるか、という問題が残ります。
この場合、「次のループでエラーを検知するのを待つ」という処理で対応する、と腹を括りました。
なぜなら、repeat..... のエラーは、積り積って発生することを経験的に知っていましたので、それまで通信障害したまま走って貰えばいい、と割り来って考えることにしました。


結論としては、

(1)http.HandleFunc()は、Webからの接続要求時に、飛される先の関数を記述するもの(コールバック関数)であり、
(2)そのコールバック関数の中だけで、入出力処理がしたいのであれば、ループを壊さないような工夫をして、上手く運用すれば、上手くいく(ことがある)

という結論になりそうです。

 

2023,江端さんの技術メモ

公開回、秘密鍵の対応

log.Fatal(http.ListenAndServeTLS(*addr, "./cert.pem", "./key.pem", nil)) // localhost:8080で起動をセット

if httpErr = http.ListenAndServeTLS(*addr, "./fullchain.pem", "./privkey.pem", nil);

ということで、 cert.pem = fullchain.pem  key.pem = privkey.pem で良いのだろう

Let's encrypt を試してみた件(整理は明日)

2023,江端さんの忘備録

今、ガリガリと、英語のカンファレンスペーパーを書いています。

I'm scribbling away and writing a conference paper in English.

(私の執筆スタイルについては、こちらをどうぞ)

(For more information on my writing style, please click here.)

翻訳エンジンがあるからできることです。

This is possible because of the translation engine.

-----

私、一度、英文チェックの外注を通してから論文を学会に投げたら、学会のレビューアーから、

Once I pitched a paper to a conference after going through an outsourced English language check, from a reviewer at the conference, I was given the following message.

『英文がなっていない』

"Your English sentence is not good enough"

というレビューが返ってきたことがあります。

その件を、外注先にクレームとして報告したら、慌てて担当者を交代させてきました。

When I reported the matter to the subcontractor as a complaint, they rushed to replace the person in charge.

この外注先、いつもエラそうに、私の英語の品質に最低の評価結果を付けて戻してくるので(そんな、いらんこと、せんでもいいのに(多分、うちの会社が頼んでいるんだろうが))、久々に胸のすく思いがしました。

This subcontractor, who always comes back with the lowest rating on the quality of my English (even though they don't have to do that (maybe my company is asking them to do it)). Anyway I had felt happy for long time.

しかし、その後、私は、外注チェックの依頼をしなくなりました。

After that, however, I stopped asking for outsourced checks.

腹が立ってきたからです。

I was getting angry at the conference.

『私の英文が気にいらないなら、それならそれで構わん。それを理由にリジェクト(却下)してもらって結構だ』

"If you don't like my English, that's fine, and you can reject it for that reason."

という気持ちになりました。

I felt that.

私的な見解ですが ―― 現在のアカデミズムに決定的に欠けているのは『思いやり』なんじゃないかなぁ、と思うのです。

-----

確かに私たちノンネイティブが書く英語は、ネイティブから見れば、不自然なものかもしれません。

It is true that the English we non-native English speakers write may be unnatural from the perspective of native speakers.

勿論『意味が通じない』というのであれば、批判されて仕方がないと思いますが、『不自然』であるというコメントには、納得できません。

Of course, if it 'doesn't make sense', then I guess I can't help but be criticized, but I don't agree with the comment that it is 'unnatural'.

こちらにも書いていますが、私は、英語の種類は、世界の国の数だけ、あるいは世界の人の数だけある、と思っています。

As I wrote here, I believe that there are as many varieties of English as there are countries in the world, or as many people in the world.

 

『自分がラクして読めない英文を、寛容に受けいれることが、インターナショナルであり、多様性だろうが』と思うのです。

I think, 'Tolerance and acceptance of English texts that you cannot read with ease is what makes us international and diverse'.

-----

別の方向からも考えてみました。

I thought about it from another direction.

最近、「異世界ファンタジー」流行っているじゃないですか(流行っているんです)。

Recently, "otherworldly fantasy" has become popular (it is so).

で、ここで、『世界共通語が日本語であり、アカデミズムの世界では、日本語が研究分野の共通言語である』という異世界を想定します ―― ファンタジーの要素はなさそうですが。

So, here we assume an alternate world where 'the universal language is Japanese, and in the world of academia, Japanese is the common language of research fields' -- although there does not seem to be an element of fantasy.

そこに、漢字が誤記だらけで、"てにをは"が滅茶苦茶、関係代名詞"that"をそのまま「それは」とか翻訳したような文が提出されたとしたら、

If a sentence was submitted that was full of kanji errors, "te ni wo ha" was a mess, and the relative pronoun "that" was translated as "that",

『さすがに、これは読みにくいだろうなぁ』

'As expected, this will be hard to read'

とは予想できます。

そして、レビューアーの私は、

And I, as the reviewer, might responce the following,

『日文がなっていない』

"Your Japanese sentence is not good enough."

と返事をするかもしれんなぁ、と。

-----

あれ? というとは、私の論文の英文は、『そういう感じの英文』だったということ?

Huh? Does that mean that the English sentence of my paper was 'that kind of English sentence'?

と、今、いきなり弱気になっています。

And now I am suddenly feeling vulnerable.

2023,江端さんの忘備録

シニアは「窓際」というイメージがあります。

Seniors workers have an image of being "window-dressers".

『楽しい「追い出し部屋」ライフ』という観点からも、プログラミング技術の取得はお勧めです。

しかし、今の私は、窓の外にいます ―― 「屋外の工事現場」です。

But now I am outside the window -- an "outdoor construction site".

一人の労働者として、道路工事や建設現場でがんばっている高齢の職人さん達をみると、肩を組んで、歌いながら、一緒にお酒を飲みたい、という気持ちになります ―― 本当です。(私は、今、断酒中(4年目)ですが)。

As a worker, when I see elderly craftsmen working hard at road and building construction sites, I want to rub shoulders with them, sing with them, and have a drink with them -- really. (I am currently in my fourth year of sobriety).

-----

私の今の仕事を端的にいうと、「(有)江端ソフトウェア開発」という会社の個人事業者です。

To put my current job in a nutshell, I am the sole proprietor of a company called "Ebata Software Development, Inc."
(*)新会社法施行後「有限会社」は消滅していますが、ここでは、『有限責任』の概念として使用します。

但し、(1)発注仕様書を自分で作り、(2)納期を自分で決定し、(3)完工後のメンテナンスは自分の気分次第、という、他のソフトウェアの外注会社から見れば『激怒される』ような内容ですが。

However, at this company, (1) I make the order specifications myself, (2) I decide the delivery date myself, and (3) maintenance after completion depends on my own mood. From the perspective of other software outsourcing companies, this is the kind of work that would make them "furious.

まあ、だから「(有)江端ソフトウェア開発」であって、「(株)江端ソフトウェア開発」ではないのです。

Therefore, the company is not ordinary one.

-----

この状況は、深刻な人手不足がもたらしているのかもしれません。

This situation may be brought about by a severe shortage of labor.

新入社員の段階で、『上流工程』だの『コンセプト』だのと言うことはできても、モノを作った経験がないエンジニアが大量に送り込まれてくるからです。

This is because a large number of engineers are sent in at the new hire stage, who can talk about "upstream processes" and "concepts," but have no experience in creating things.

だから、私は、「昔取った杵柄(きねづか)」を、手放すことができないのです ―― 今や、私の「杵柄」はボロボロです。

That's why I can't let go of my "kinezuka" -- my "kinezuka" is now in tatters.

正直、私は『シニアになれば、新しい技術を使い倒す若者によって居場所がなくなる』と信じていました。

Frankly, I believed that 'when I become a senior, I will be displaced by young people who will use up all the new technology.

ところが、蓋を開けてみれば、道路工事や建設現場やシステム開発だけでなく、日本全体が「シニア」をアテにしているという状況(惨状)です。

However, when we open the lid, we find that not only construction sites and system development, but also the whole of Japan is relying on "seniors" (a disastrous situation).

-----

まあ、これ「彼ら」が悪いというよりも、「雇用主(会社)」が悪い。

Well, this is not so much "their (the newcomer's)" fault, but rather "the employer's (the company's)" fault.

趣味でも勉強でもバイトでも構いませんが、自力でシステムを組み上げたこともない人が、どうやってモノを作れるのか、私は今でも分からなのですが ―― 会社の募集要項に、確かに書かれているんですよね。

It doesn't matter if it's a hobby, study, or part-time job, I still don't know how a guy who has never put together a system on his own can build things.However the application guidelines certainly say that.

『プログラミング経験は、採用の要件ではない』、と。

Programming experience is not a requirement for employment."

確かに、プログラミングだけができても駄目ですが、プログラミングの経験すらない人が、システムを語れるのか、私には甚だしく疑問なのです。

Well, it is true that it is no good if one can only program, but I highly doubt that a person without even programming experience can talk about systems.

私は、過度な現場主義を嫌悪していますが、一人で、スクラッチからシステム(Webページくらいでも良い)を組み上げる経験をしたことをない人間を、モノ作りの仲間として認めるのは、大変難しいです。

I detest excessive fieldwork, but it is very difficult for me to accept a person who has never built a system (or even a web page) from scratch by themselves as a member of the manufacturing community.

-----

では、江端は入社時にプログラミングができていたのか?

So, was Ebata able to program when he joined the company?

実際のところ、入社時の私のプログラミングは、N80-BASICクラスの「動いているだけ」という程度のものでした。

In fact, my programming skills at the time I joined the company were about the N80-BASIC level, so called "just working".

本格的なコーディングは、入社後だったと思います ―― なので、入社時の私のスキルは、今の若い人と同じです。

I think the real coding started after I joined the company -- so my skills at the time I joined were the same as a young person today.

後は、個人的なイデオロギーの違いがあるだけです。

The rest is just personal ideological differences.

『"動いていない"は、"無い"と同じである』と、私は信じていますので。

I believe that "not moving" is the same as "not existing".

-----

とは言え、「(有)江端ソフトウェア開発」は、プログラミングだけしていればよい、という会社ではありません。

However, "Ebata Software Development" is not a company that only needs to do programming.

20ページのプレゼンテーション資料を1時間で作ったり、1日で研究報告書を執筆しろと言われたり、ソフト外注先のプログラムの動作不良を潰すことを頼まれたり、無茶な学会発表を命じられたり、予算の計算したり、各種の発注作業をしたり、大学の授業を受けたり、講義したり ――

The company was asked to create a 20-page presentation in an hour, write a research report in a day, crush a software subcontractor's program malfunction, present at a conference, calculate budgets, place various orders, take university classes, give lectures, and so on. --

それでも、

Howeve, it is

―― 『動かせ』と言われたら、"No"と言わない(言えない)会社

"The company that does't or cannot say "No", whenever asked to move something"

です。

『自作のプログラミングコード一本で、研究原資という"タマ"を取りに行く』

2023,江端さんの忘備録

コーディング(プログラミング)は、バグの発生理由やAPI仕様が分からくなって、結構な頻度で「ハマる」ことがあります。

Coding (programming) can get "stuck" quite often, due to bugs or confusion about API specifications.

私のやっているような、専門(カルト)分野になりますと、それについての説明記事すら見当たらない、という状況になります。

Specialized (cult-like) field like the one I work in, I can't even find an article explaining it.

まあ、だからこそ、私は、自分のハマった内容は、それを『キレイに纏めないで』ブログで公開しています。

Well, that's why I publish what I have faced the problem on my blog, without 'neatly summarizing' it.

私のゴミのようなメモでさえ、何の情報もないよりは、はるかにマシなのです。

Even my garbage notes are far better than no information whatsoever.

-----

さて、このコーディングの「ハマる」問題は、その対応のためにムキになって、酷い時には、2~3日の時間を丸々持っていかれたあげく成果ゼロ、ということもあります。

Now, this coding "getting stuck" issue is one that I get really pissed off to deal with. In the worst case, it can take up two or three full days of my time, with zero results.

このコーディングの沼から抜け出すためには、「打ち切る」という勇気が必要です。

To get out of this coding quagmire, we need to have the courage to "abort" it.

ところが、この「打ち切る」というのが、本当に難しいのです。

However, this "abort" is really difficult.

『サンクコストの呪い』というやつです。

It's called "The Curse of Sunk Costs."

―― エジソン、バカ

-----

こういう場合、『有識者の方にメールで質問』をしています。

In cases like this, I 'email questions to the experts'.

こうして、その問題から一時離れます。

Thus, I temporarily step away from the problem.

もちろん、これは、相手に迷惑をかけるシャレにならない方式ですし、そもそも失礼です。

Of course, this is a shameless method that inconveniences others and is rude in the first place.

ですので、普段から相手との信頼関係を構築しておかなければなりません。

Therefore, I must build a relationship of trust with them on a regular basis.

その信頼関係とは何かと言えば ―― その方からの質問に対しては『自分の持っている全ての知見を、最速かつ無条件で開示する』ということです。

What is that relationship of trust? When that person asks me a question, I have to 'disclose all the knowledge I have in the fastest and unconditional way possible".

これを、日常的に行っていなければなりません。

This must be done on a daily basis.

これを「人脈」といいます。

This is called "human networking".

名刺を交換することは、「人脈」とは言いません。

Exchanging business cards is not "networking".

人脈には、ちゃんと情報交換と信頼関係という「血液」を流し続けなければならないのです。

We must keep the "blood" of proper exchange of information and trust flowing through our connections.

「血液」が流れていない「人脈」は、ただの「管」です。

A "networking" without "blood" is just a "tube.

-----

逆に言うと ―― 私は、思い出したように、困った時だけ私を使おうとする奴に対しては、意図的に(悪意的に)対応しません。

Conversely -- I will not intentionally (maliciously) respond to anyone who tries to use me only when they are in trouble, as I recall.

私の情報提供に対して、礼の一つも寄越してこないような人間に対しては、「管」そのものを切断します。

I have cut off the "tube" itself to anyone who does not send me even a single thanks mail for the information I provide.

まあ、このような狭量の人間を『大人げない』というのでしょうが ――

Well, I guess you could call such a narrow-minded person 'childish', however,

私の知る限り、世の中の大半の大人は、『大人げない』です。

As far as I know, most adults in the world are not 'childish'.

私は、過去は振り向かない人間です ―― 特に、他人の過去は。

2023,江端さんの技術メモ

T研究所のKさん。ありがとうございました。

 

(4)PruneClusterにおいて、クラスタリングを解除する方法 → leafletView の定義の後に、「leafletView.Cluster.Size = -1」のよう     に負の値を設定することによって、実現可能です。     - 参考URL:https://github.com/SINTEF-9012/PruneCluster/issues/52

2023,江端さんの忘備録

現在、横浜市交通局さんから提供して頂いている情報を使って、バスのリアルタイム情報を表示させる作業をしています。

I am currently working on displaying real-time bus information using information provided by the Yokohama City Transportation Bureau.

「Protocol Buffersって何? 」から、「公共交通オープンデータ」を攻略する

昨夜、コーディングを再開したら、交通データが全く表示されなくなっていました。

When I resumed coding last night, the traffic data was not showing up at all.

真っ青になって、プログラムを見直してみたのですが、障害の原因となるような箇所が見つかりません。

In a panic, I reviewed the program, however I could not find anything that could cause the failure.

散々調べた挙げく、妙な短文データが表示されているので、これをデコードして、ようやく原因が分かりました。

After much investigation, I finally found the cause of the problem by decoding the strange short text data being displayed.

―― 深夜は路線バスは走っていません

"No buses running late at nigh"

-----

まあ、バスが走っていない時間にコーディングしている私が悪いんですけどね。

Well, it is my fault for coding at a time when buses are not running.

それにしても、こんなしょーもない理由で、大切な深夜の2時間がふっとんだかと思うと、なんともいまいましいです。

Still, it's a damn shame to think that two precious late-night hours were lost for such a trivial reason.

2023,江端さんの忘備録

今夜、異動先の部署のキックオフの飲み会に参加してきました。

Tonight I attended the kick-off drinks for the department I am transferring to.

こんな私でも、節目の行事は、大切だと思っています。

『なんだかんだいって、セクショナリズムの対抗手段は、定期的な飲み会である』

Even I would like to cherish milestone events.

お開きのところで、挨拶を求められたので、一言だけ申し上げてきました。

At the close of the meeting, I was asked to say a few words.

「本日、聞いたお話は、3年間は『書きません』ので、ご安心下さい」

"I will not write about what I heard today for the next three years"

-----

一瞬、『この人、何を言っているの?』という風の顔の後で、「その"話"とは何だ?」と一斉につっこまれましたが、私はにこやかな笑顔を見せたまま、そのまま散会しました。

Just after everyone looked like, "What is he talking about?, they asked me "What is this 'talk'?" immidately. However, Smiling at them and I left soon.

今後は、節目の行事すら、呼ばれなくなるかもしれません。

In the future, I might not be called even milestone events.

2023,江端さんの忘備録

一年でもっとも嫌いな「月」を挙げろと言われれば、私は「4月」を挙げます。

If you ask me to name my least favorite "month" of the year, I will name "April".

■これまで動かなかった人々が、虫のようにわらわらと動き出すをの見るのが不快です。

- I am uncomfortable to see people who have never moved before start moving like insects.

■着なれないスーツを着て緊張した顔をしている若者が、これから挫折していくことになる現実に、気分が暗くなります。

- My mood darkens at the reality that these young men, looking nervous in their ill-fitting suits, are about to fall behind.

■この若者の中の何人かが、そう遠くない未来(とりあえずゴールデンウィークあたり)に出社しなくなり、さらに高い確率で、心の病に罹患することに憂鬱になります。

- I am depressed that some of these young people will stop coming to work in the not-too-distant future (around Golden Week for) and, at an even higher rate, will suffer from mental illness.

―― 国家レベルの「心の崩壊」が始まっている

そして、

And

■様々な人事発表で、私よりもはるかに若い人が、偉くなって、壇上から期首方針を述べているのを見るのは、気分の良いものではありません。

- It is not a pleasant feeling to see someone much younger than I am at various personnel announcements, rising to greatness and speaking from the podium about the policy for the term.

その度に、『彼と私は、何が違っていたのだろう?』と考えてしまう自分に自己嫌悪します。

Every time I do, I hate myself for thinking, 'What was so different about him and me?'

いや、判っているんですけどね。

Well, I know the reason well.

こちらのコラムでも、『あなたより優秀な後輩は、あなたの後に山ほど入社してきて、簡単にあなたの上司となります』と書いています。

In this column, I also wrote, 'A lot of juniors who are better than you will join the company after you, and they will easily become your boss.

ただ、頭では分かっているのですが、実際に知っている人が、どんどん出世(?)している様を見るのは、そこそこキツいものなのです。

I know this in my head, but it's hard to see someone I actually know moving up in the world.

-----

江端:「ついつい、『彼と私は、何が違っていたのだろう?』と考えてしまうんだよな」

Ebata: "I tend to think, 'What was different about him and me?'

嫁さん:「それは、もう『何もかも』でしょう」

Wife: "Needless to say, that would be 'everything'"

と嫁さんは言います。

My wife says,

「出世をする人は、会社に利益を与える人や、その気概を持っている人だけだよ」

The only people who get ahead are those who benefit the company and have the chutzpah to do so."

2023,江端さんの忘備録

出生率の低下の一因(というか主要因)は、非婚化です。

One factor (or rather, the main factor) in the decline in the birth rate is the nonmarriage rate.

どうして、非婚化が進行しているかというと、その原因ははっきりしています。

The reasons for the growing number of unmarried people are clear.

―― 『結婚の価値、良さ、メリット』を、若者に対して言語化できない、私(たち)の無能

"My (our) inability to verbalize the "value, merits and advantages of marriage" to young people"

です。

-----

先日、ニュースで、『非婚女性のウェルビーイングが、既婚女性のウェルビーイングを越えたことが、統計で示された』という話を聞いて ―― 『いずれ、そのデータが出てくるだろう』とは予感していたのですが ―― それでも、ショックを受けています。

The other day I heard a story in the news that 'statistics show that the wellbeing of non-married women has surpassed that of married women' -- I had a hunch that 'eventually the data would come out' -- but... -- I was still shocked.

以下の表は、ちょうど10年前に私の予測した非婚化の予想です。

The following table shows my predictions of nonmarriage just 10 years ago.

私自身は、「非婚」が、価値のある人生の選択であることは、よく理解しています。

I myself understand that "non-marriage" is a worthwhile life choice.

しかし、同時に「結婚」もまた、価値のある人生の選択であることも知っています。

But at the same time, we know that "marriage" is also a worthwhile life choice.

-----

もちろん、非婚や結婚が、自分の選択だけで決まる訳ではありません。

Of course, non-marriage and marriage are not determined solely by one's choice.

しかし、現在が「結婚」が恐しく難しい時代であることは、データを見るまでもなく分かっています。

However, we don't need to look at the data to know that "marriage" is a terribly difficult time today.

以下のグラフは、10年前の私の予測です。ざっと見たところ、非婚化は、私の予測より加速されているようです。

The following graph is my prediction from 10 years ago. At a quick glance, it appears that the rate of nonmarriage is accelerating faster than I predicted.

現在の結婚の難しさは、私の体感で、私の時代の『10倍以上』は難しく、やろうと思えば、数値で叩き出せると思います。

The difficulty of marriage today is, in my experience, 'more than 10 times' as difficult as it was in my day, and I think I could beat it out of you numerically if I wanted to.

それはさておき。

Aside from that.

-----

『結婚の価値、良さ、メリット』を、若者に対して言語化できない、私(たち)無能 ―― について異議はないのですが ――

I have no objection of "My (our) inability to verbalize the "value, merits and advantages of marriage" to young people", however,

では、私たちの時代に、『結婚の価値を、きちんと言語化してくれた先人がいたか?』だろうか、と考えてみました。

So, in our time, 'Did any of our predecessors properly verbalize the value of marriage?' I wondered.

いや、いなかったぞ。

No, they weren't there.

たった一人を除いて、誰もいなかった。

There was no one there except for one person.

「結婚って、良いものですか?」

-----

では、私(たち)は、どうやって結婚を選択してきたのか?

So how have I(we) chosen to get married?

当時の人も、私たちと同様に、結婚の価値を言語化することはできなかったけど、『私は、結婚していた"その人"を信じることができた』とは言えると思うのです。

People then, like us, could not verbalize the value of marriage, but I think we can say, "I could believe in the 'person' who were married to".

では、"その人"とは誰か?

So, who is "the person"?

それは、親であり、先輩であり、高齢者であり、社会でした。

It was parents, seniors, the elderly, and society.

私(たち)は、結婚を支持する(または同調圧力をかけてくる)社会を、とりあえずは信じていたのです。

I (We) believed, for the time being, in a society that supported (or was sympathetic to) marriage.

-----

この考え方を拡張していくと ――

Extending this idea --

非婚化とは、

What is nonmarriage?

- 結婚を望まない人の価値観を認めず、

- Not recognize the values of those who do not wish to marry,

- 結婚を望む人の望みを叶えられない社会を作り(あるいは、その社会を放置し)、

- Create (or leave in place) a society that fails to fulfill the desires of those who wish to marry,

- 結婚の価値を、自分の言葉で語ることもできない、

- Not speak of the value of marriage in his own words,

そういう、無能な私(たち)に対する「痛烈な批判」である、という結論に帰着する訳です。

I can only conclude that this is a "scathing criticism" of my (our) incompetence.