Ubuntu上のAsyncで遅延 – BlackJumboDog CoreCLR

ずーっと気になっていたんですが、Ubuntu上でサーバーのTCPソケットをAcceptAsyncかけていたら、しばらくアクセスがない状態だと1秒程度の遅延が発生していました。そして、連続したアクセスだとこれは起きなかったんです。

元々のBjdではWhileとSleepによるポーリングを行っていたので、おそらくそんなことは起きなかっただろうと思っています。(そもそも、Begin/Endが動かなかったので、根拠はない!)

同じことが、ManualResetEventSlimeでも起きました。ある程度時間がたったときに、シグナルセット後のWait解放が1秒くらい。これ、Windowsでは起きなかったんですよね。

正直、そこまでプラットフォームに詳しい人間ではないので、なぜこうなるのか?は理解できませんでした。ただ、どうすれば?に関しては、「深い眠りにつかないようにする」っていう発想で回避しました。

https://github.com/darkcrash/bjd5/commit/a9049f8630d2e788dda19065026c415654efcd05#diff-c042d296432145429c9f5f4d27bfef99

     -            tTcp.Wait(this.Kernel.CancelToken);  
 94   +            while (true)  
 95   +            {  
 96   +                if (tTcp.Wait(2000, this.Kernel.CancelToken))  
 97   +                    break;  
 98   +                if (tTcp.Status == TaskStatus.Canceled)  
 99   +                    break;  
 100  +            }

Waitを2秒までとして、完了時はループを抜け、キャンセル時もループを抜けます。こうすることで2秒に一回このWaitが実行されます。そして、結果として遅延1秒はなくなりました。

SpinWaitの絡みとか、タイムスライスのルールとかありそうなんですが、ブラックボックスです。Darkが作るBlackなだけに・・・

これが、Kernelによるものなら、今後もこういう仕様ということになるでしょうし、.Net Coreのものであれば、改善されていくかもしれません。ので、現時点ではこのコードは、一つの回避策として整理してくださいませ!

それでは!

環境によるパスの違い – BlackJumboDog CoreCLR

前回から、Option.iniが読めてないのは見事的中しました。

https://github.com/darkcrash/bjd5/commit/789b737402a8e16b4d99147c6471eb83a426fce3?diff=unified#diff-e8a8a3be0e352480bc87c1f17ebc86bb

Windowsでは「\」をパスに利用しますが、Linuxでは「/」を利用します。ここにリテラルで「\」があったために、パスを拾えていなかったようです。これは、System.IO.Path.Combineメソッドを利用して対処しました。

でも、なんでこれで大丈夫なのだろうか?

という疑問が出てきましたので、ちょっとだけソースを追いかけてみました。

こうした環境の違いがあるために、.Net CoreのライブラリではPlatformによる違いを吸収する方法をとっているようです。

これが、Bjd(アプリ)が直接利用しているPathクラスの中身。(正確なバージョンまでは未確認。きっと多分)

System.Runtime.Extensions System/IO/Path.cs

中では「DirectorySeparatorCharAsString 」というフィールドを利用して、結合していますが、この実体はここにいません。

分割クラス(partial)となっており、

System.Runtime.Extensions  System/IO/Path.Windows.cs

System.Runtime.Extensions  System/IO/Path.Unix.cs

という風に複数定義されたものがありました。Unixでは「/」Windowsでは「\」(エスケープのため2文字なだけ)となっています。

これは、以下のプロジェクトファイルでターゲット($(TargetsUnix)、$(TargetsWindows))による切り替えが確認できます。

System.Runtime.Extensions.CoreCLR.csproj

つまり、プラットフォームごとに作られているものが違うということですね。

 

でも

2016-01-09 (1)

 

こ、今度は、BeginReceiveがないですと!!ポートが使われているよーはサービスを止めればよいとして、Windowsでは動いてるのに!!これも追いかけていこうじゃないですか!

それでは、また

 

 

Ubuntuで動いた!? BlackJumboDog CoreCLR

まずは無事に、動きました!DNX_TRACE=1から直接問題を検出できたわけではないですが、これを見ることによってどこまで動いているかの見当をつけることができたのは、StackOverflowExceptionのStackTraceを見れるのと見れないの違いくらいあるんじゃないかと思います。

2016-01-09

原因は、Consoleのサイズ取得もしくは変更をしようとしたところにありました。これは、本家Bjdにはない機能でした。GUIを捨てるときにどうしても何か見えるものをCUI上に出しておきたいと思ったのがきっかけです。Trace.Writeでトレースを出力するようにして、それをConsleに出力するためのTracelistenerを実装しています。

GitHub変更点

https://github.com/darkcrash/bjd5/commit/b42c4386866db1f681bbec13b6c20547b02e3320

Windows動かしている分には、サイズ変更できていましたが、SSH経由でそれをやると例外が発生していたようです。TryCatchを入れConsoleに出力したところメッセージが出てきましたので、取得または変更で間違いなさそうです。これもLinuxのGUI上からやったらどうなるかとかはわかりませんが、そんなことするなよって話もありつつ、やるならできない場合を考慮する必要があるようですね。

そもそも、何よ!って人に向けて

MSDN ライブラリ TraceListener クラス

これは、.NetFrameworkに昔からある機能で、Traceクラスを用いて、Writeメソッドやら、WriteLineとかで出したものを、受け取って何らかの処理をする機能を提供するための基底クラスです。ただ、.Net Core としても、Windows (ETW) があるようなので、Linuxでも動くならそっちのほうがよいでしょうね。

スクリーンショット見ると、サーバーは何も起動した形跡がないというオチが待っていました!おそらく、Option.iniを開けてとかその辺じゃあないのだろうかと思っていますが、本当に動くようになるまで戦いは続きます。

それでは、また!

 

 

 

 

 

最近取り組んでいること – BlackJumboDog CoreCLR ConsoleApp

こんにちは!

Blogを書いたのにあまり自己紹介とかもないので、少しづつ自分の取り組んでいることをここに残していこうと思います。元々Facebookで、画像アップロードしたりしてひっそり遊んでいました。こうやって活字にするはちょっとハードルがありますが、伝えていくという意味で、至らぬながらも挑んでいこうと思います。

BlackJumboDogのCoreCLR化

ということで、実はこのBlackJumboDogというのを使ったことはありませんでした。まずは、リンクを以下に張っておきます。

サイト:http://www.sapporoworks.ne.jp/spw/

CodePlex:http://blackjumbodog.codeplex.com/

GitHub:https://github.com/furuya02/bjd5

これ、すごいんですよねー!いろいろなサーバーの機能が詰め込まれている、C#で書かれてたアプリケーションなんです。HTTP、FTP、DHCP、DNS、SMTP、POP3、TFTP、Sip etc..

と全部で16ほどの機能を持っています。

これを、CoreCLRで動かしてみたいじゃない・・・?あれ、私だけ?製作者の方に許可をいただいて、がっつりやらしてもらうことにしました!

個々を見ていったとき多機能な部分もありますが、やはりお手軽さが非常に強いのかなぁって思いまして、option.ini(すべての設定を持つ構成ファイル)を本家のものでそのまま動かせるようにしてしまおうじゃないの!って考えています。

あ、そもそもCoreCLRなによ!?って方ですが、.NET Coreっていうものが作られています。これが、以下にあるように

http://www.dotnetfoundation.org/netcore

.NET Core has two cheap jerseys major components. It includes a small runtime that cheap jerseys free shipping is built Stellenangebote from the same codebase as the .NET Framework CLR. The .NET Core runtime includes the same GC Deadline and JIT (RyuJIT), but curves doesn’t include features like cheap jerseys Application Domains or Code Access Standard Security. The Blogはじめました runtime is delivered on wholesale MLB jerseys NuGet, via the Microsoft.CoreCLR wholesale MLB jerseys package.

ということで、かなり簡単に言ってしまうと.NetFrameworkからアプリケーションドメインとコードアクセスセキュリティを除外した軽量なフレームワークですよってことですね。ライブラリ(DLL)はNuGetから提供される。(事前にインストールしない)

これを動かすプラットフォームの一つにCore CLR(CommonLanguageRuntime)があるってことなんですね。ここで動くってことは、一応ASP.NET5上やらUWPからも実行できる可能性があるってことなんです。

可能性があるって言っているのは、実際にそれぞれの環境になると様々な制約があるので、コンソールアプリケーションのようには動かすことはできないことを意味しています。

ただ、Consoleアプリケーションは、特に制約がありませんので、まずはここを今目標として、せこせこやっているGitHubのリポジトリがこちらです。

https://github.com/darkcrash/bjd5

CoreCLRというブランチを作って、そこでせこせこ作っています。現在14/16まで移植していて、もうすぐ移植は完了し、デプロイメント手法の実装に移る予定ですー。

以下、CoreCLRとして、WebServerを動かしている様子です。

 

ある程度形になったら、また、ここで報告させていただきます!

それでは、また!