ぼうメモ帳

2017-01-09 今更の議論 このエントリーを含むブックマーク

まさか仕事中に、検査例外と非検査例外議論が出るとは思わなかった。

監視ログに出力されていないエラー存在し、エラーログのみに出力される例外存在し、それがRuntimeExceptionを継承した例外クラスだったから、RuntimeExceptionがいけないんだと。

いや、それ、単に例外キャッチ方針監視ログへの出し方の問題でしょ。いくら監視ログへ出力する内容を精査したいからって、業務APで細やかにハンドリングした結果、Catch漏れルート存在したから、RuntimeExceptionが悪いって、短絡過ぎる議論だったので、検査例外Java言語の失敗の一つという結論は10年前には出ましたし、事実Java以外では検査例外実装されていません、と一言(嘘、二言)で一蹴しておいた。(もちろん、本心ではそんなことは思っていないが、まま仕方なし。)

ところで、11月から上司が変わったのだが、エンタープライズな開発にJavaは向いていないという点で、その上司意気投合してしまった。かと言って、新しい言語を作っても、会社から爪弾きにされる(過去事例あり)し、どうしたものかねと会話をしていた。システム開発って、複雑なようでシンプルで、一部の機能を除いて、複雑な機能必要ない。

例えばコレクションに関して言うと、ぶっちゃけ、ListとMapさらにはArrayListとHashMapばかりで、それ以外は利用してなくね?さらに、全体の半分はBean系ではないかと思わせるぐらい、無駄にBean系クラスが多い。なので、最近は、開発規模が500KSと言われても、実際に意味のあるビジネスロジックは200KS相当と考えるようにしている。

と考えれば、ビジネスロジック抽象化して記述する方法と、それらが利用するライブラリ群やそれらを利用するフレームワーク群をJavaで書くみたいな感じができると嬉しい。

トラックバック - http://d.hatena.ne.jp/susumu/20170109

2016-12-29 突貫マネジメント このエントリーを含むブックマーク

はたまたトラブルシュート案件です。

先週中旬ごろより、第三者という立場問題PJに監査的に関わっていたのですが、クリスマス休暇3日間を対策検討に費やしていたら、なぜか今週の月曜日お客様説明資料内の体制図でチームを持つことになっており、その担当範囲が、1月中旬までに通信ライブラリ(6KS)を仕上げるというモノでした。

さらに、チームはまだ結成されておらず、26日時点では、自分の部下1名だけを連れて、参戦です。他のチームメンバは、1月4日〜5日に合流するという形です。

全員集まると、私を含めて8名体制。部下1名以外は全員初対面。

突貫でチームビルドを行い、6KSを仕上げ、単体試験、結合試験を乗りきって、1月中旬業務結合試験に間に合わせる必要があるという。。。

さて、こんな突貫マネジメント経験は初めてで、何をどうしたら良いのやらということで、1月4日初日から設計製造に入れるよう、いま、準備をしています

と、1/4までに準備して、PM層に説明し、何かあっても責任を取ってもらえる準備を行う必要があります

(まだクビにはなりたくないので、最優先事項です。)

いや〜 この突貫マネジメントをやりきれたら、アーキテクト止めて、PMでもご飯食べていけるんじゃね?と思ってみたり、みなかったり。

なお、昨今の長時間労働等の労務管理に対する風当たりの強さもあり、当然、営業日オンリー&1日6時間(2時間バッファ)で作業見積もりしたスケジュールを組んでますよ。そのために、かなりお高くつきましたが、エース級PG1名、準エース級PG2名を、さら自由に動かせて瞬発力の高い若手3名、最も信頼できる部下1名を1ヵ月限定で他PJから引き抜いてきました。(上位マネジメント層には感謝。)

さらに、労務管理の緩い管理職2名(部長)の協力を取り付け、休みの日にも関わらず、準備ができた所から順次RVを頂いている状態です。今日はWBSを見てもらいましたが、凄い五月雨線表に、マネジメント層が全員絶句してました。そりゃそうですよ。1月4日からの2週間分を全て時間単位スケジュールを立ててますからしかも、全タスクについて、想定作業量を想定項目数をベースに算出しているので、なんかやれそうな気がしてくるというWBSです。

とは言え、初めての突貫マネジメントなので、とにかく怖い。。。

最後は、私と部長×2名の3名で、往年の突貫プログラミングを行わないといけないかもと、冗談交じりに話はしていましたが、とにかく突貫ばかりです。とりあえず、部長には正月明けの3連休は空けておいてくださいとお願いしておきました。

あと1ヵ月早く開発を決定できていたら、どんだけ楽だったか。。。

ちなみに、私は明日仕事納めの予定です。一応、管理職連続勤務だけは意識しろと言われており、明日30日で12日目なので、31日はお休みを貰おうかと。

トラックバック - http://d.hatena.ne.jp/susumu/20161229

2016-12-23 Java + Windows の Socket 通信 このエントリーを含むブックマーク

Java + WindowsにてSocket通信を行うAPの開発が必要となったので、実験メモ

要件

  1. サーバクライアントは同一サーバで、windowsである
  2. プログラムは、Javaで開発する
サーバ要件
  1. 待ち行列制御したい
  2. タイムアウト済みのクライアントとの通信は、即時に無効を検知したい。
  3. 待ち行列制御をAPで行いたくないので、待ち行列バックログだけで管理するためにサーバ側はシングルスレッドで処理したい
クライアント要件
  1. 一定時間待ち行列上に存在した場合は、クライアントは依頼を送信せずに、処理を諦めたい
  2. クライアントにて異常と判断した場合は、可能な限りサーバ側にて処理が行われないようにしたい
  3. サーバに依頼した処理が仕掛ってしまった場合は、処理の中断はあきらめるものの、サーバ側に諦めたことを伝えたい

普通はほとんどありえない要件ですが、今回ばかりは特別事情ということで…

プロトコル(1)

  1. 接続: クライアント#connect -> サーバ#accept
  2. 要求: クライアント#send -> サーバ#recv
  3. 結果: クライアント#recv <- サーバ#send
  4. 切断: クライアント#close , サーバ#close

なお、recvのタイムアウトを5秒とする。以降、xx秒経過を(xx)と表現

検討実験(1−A)

backlogに滞留しているケース。

クライアント側の状況>

  1. 接続(00): クライアント#connect -> OK
  2. 要求(00): クライアント#send -> OK
  3. 結果(05): クライアント#recv -> Timeoutエラー
  4. 切断(05): クライアント#close -> OK

これでは、送信した依頼はまだ実行されずにタイムアウトしたのか、それともサーバ側の処理時間が長くてタイムアウトしたのかが分からない。

というのも、synsyn/ackackの流れは、ServerSocket#bind(listen)すると、OS側で自動で行われるため、クライアント側のconnectタイムアウトでは、サーバ側のaccept前でのタイムアウトか、accept後でのタイムアウトかを判定できない。

しかも、send/flushは成功している以上、サーバ側に依頼を受け取って貰えたように見える。

だが、処理結果は受信できなかったため、依頼は失敗したとして、クライアント側の処理を継続する必要がある。

サーバ側の状況>

  1. 接続(10): サーバ#accept -> OK
  2. 要求(10): サーバ#recv -> OK
  3. 結果(10): サーバ#send -> OK
  4. 切断(10): サーバ#close -> OK

クライアントからaccept成功し、依頼を受信したので、処理を実行し、結果を応答できた。すばらしい。

<結果>

クライアントは処理を失敗として扱い、さらに、サーバ側で処理してしまったかどうかが判断できない。サーバ側は処理を成功として扱った。結果、クライアントサーバ間では、状態の不整合が発生する。これでは、よろしくない。

プロトコル(2)

  1. 接続: クライアント#connect -> サーバ#accept
  2. 確認: クライアント#recv <- サーバ#send
  3. 要求: クライアント#send -> サーバ#recv
  4. 結果: クライアント#recv <- サーバ#send
  5. 切断: クライアント#close , サーバ#close
検討実験(2−A)

backlogに滞留しているケース。

クライアント側の状況>

  1. 接続(00): クライアント#connect -> OK
  2. 確認(05): クライアント#recv -> Timeoutエラー
  3. 要求(--): クライアント#send -> skip
  4. 結果(--): クライアント#recv -> skip
  5. 切断(05): クライアント#close -> OK

とりあえず、要求送信していないので、サーバ側で処理していないということは確実に判定できる。すばらしい。

サーバ側の状況>

  1. 接続(10): サーバ#accept -> OK
  2. 確認(10): サーバ#send -> OK
  3. 要求(10): サーバ#recv -> 即時エラー
  4. 結果(--): サーバ#send -> skip
  5. 切断(10): サーバ#close -> OK

要求を受信できなかったので、とりあえず、クライアント側は諦めたと考えてよいだろう。すばらしい。

<結果>

クライアント側も、サーバ側も、お互いに処理を実行していないと判断できるため、状態の不整合は発生しない。すばらしい。

検討実験(2−B)

処理遅延が発生したケース。

クライアント側の状況>

  1. 接続(00): クライアント#connect -> OK
  2. 確認(00): クライアント#recv -> OK
  3. 要求(00): クライアント#send -> OK
  4. 結果(05): クライアント#recv -> Timeoutエラー
  5. 切断(05): クライアント#close -> OK

要求送信できたが、結果受信をタイムアウトしてしまった。

サーバ側の状況>

  1. 接続(00): サーバ#accept -> OK
  2. 確認(00): サーバ#send -> OK
  3. 要求(00): サーバ#recv -> OK
  4. 結果(10): サーバ#send -> OK
  5. 切断(10): サーバ#close -> OK

要求を受信できなかったし、結果を返すこともできたので、きっと、クライアントは正常に処理できたのだろう。すばらしい。

<結果>

クライアントは処理を失敗として扱い、サーバ側は処理を成功として暑かった。結果、クライアントサーバ間では、状態の不整合が発生する。これでは、よろしくない。

プロトコル(3)

  1. 設定: クライアント#Linger(true, 0s)
  2. 接続: クライアント#connect -> サーバ#accept
  3. 確認: クライアント#recv <- サーバ#send
  4. 要求: クライアント#send -> サーバ#recv
  5. 結果: クライアント#recv <- サーバ#send
  6. 切断: クライアント#close , サーバ#close
検討実験(3−A)

backlogに滞留しているケース。

クライアント側の状況>

  1. 設定(00): クライアント#Linger(true, 0) -> OK
  2. 接続(00): クライアント#connect -> OK
  3. 確認(05): クライアント#recv -> Timeoutエラー
  4. 要求(--): クライアント#send -> skip
  5. 結果(--): クライアント#recv -> skip
  6. 切断(05): クライアント#close -> OK

とりあえず、要求送信していないので、サーバ側で処理していないということは確実に判定できる。すばらしい。

サーバ側の状況>

  1. 接続(10): サーバ#accept -> OK
  2. 確認(10): サーバ#send -> 即時エラー
  3. 要求(10): サーバ#recv -> skip
  4. 結果(--): サーバ#send -> skip
  5. 切断(10): サーバ#close -> OK

確認送信に失敗したので、とりあえず、クライアント側は諦めたと考えてよいだろう。すばらしい。

<結果>

クライアント側も、サーバ側も、お互いに処理を実行していないと判断できるため、状態の不整合は発生しない。すばらしい。

検討実験(3−B)

処理遅延が発生したケース。

クライアント側の状況>

  1. 設定(00): クライアント#Linger(true, 0) -> OK
  2. 接続(00): クライアント#connect -> OK
  3. 確認(00): クライアント#recv -> OK
  4. 要求(00): クライアント#send -> OK
  5. 結果(05): クライアント#recv -> Timeoutエラー
  6. 切断(05): クライアント#close -> OK

要求送信できたが、結果受信をタイムアウトしてしまった。

サーバ側の状況>

  1. 接続(00): サーバ#accept -> OK
  2. 確認(00): サーバ#send -> OK
  3. 要求(00): サーバ#recv -> OK
  4. 結果(10): サーバ#send -> 即時エラー
  5. 切断(10): サーバ#close -> OK

結果の送信に失敗したので、とりあえず、クライアント側は諦めたと考えてよいだろう。だが、処理は行ってしまった。

<結果>

クライアント側はサーバ側にて処理が行われたかどうかは分からないものの、サーバ側もクライアントに結果を通知できなかったため、お互いが依頼をなかったことに(ロールバック)できれば、状態に相違は発生しない。まあ、良いかな。

まとめ

今回の条件である、同一サーバ内でのソケットを利用したプロセス通信であり、サーバwindowsであり、APJavaで書かれているようなケースにおいては、リスクを最小限にするために、SoLinger(true,0)をしつつ、サーバから接続確認送信から始めるようにすれば、そこそこのプロトコルができそうである

ただ、絶妙なタイミングでの障害場合検証は行えていないのと、検証そのものが難しいので、とりあえず、今回はこの設計で頑張ってみましょう。

トラックバック - http://d.hatena.ne.jp/susumu/20161223
253636