トランセンドライブラリ4:アーキテクチャの構成方法

こんにちは、今日は図書館のことについて話し続け、アイデアの支持者を見つけたいと思います。

この投稿はTranscend Library 4:Introductionの続きであり、より正確にはコメント内の議論の論理的な展開です。



コードを壊すのではなく新しい投稿を書くのはなぜですか



-簡単な理由があります。 理由。





免責事項



私は野心的で、若く、愚かで自信があります。 マキシマリズムはまだ死んでおらず、時々起こります。 それでも、多少の理にかなった推論の後、コードを開いてオープンソースに行くことは、最初の販売やスタッフを雇ってお金を稼ぐよりも、仲間の開発者を見つけるよりシンプルで現実的な方法のように思えます。



パターン



私が使用したもののほとんどは共通のパターンを持っています。 何かはありませんが、非常に一般的です。 いずれにせよ、それらを知らない人にはどんなサイトでも明確になることを願っています。 おなじみの人のために-私は名前の属性の隣になります。



TL4



非同期性


ネットワークの性質


ネットワークの性質は非同期です。 「同時に」および「瞬時に」という概念はありません。 関数呼び出しのすべての効果は、多くの理由に応じて遅れて発生します。 結果を待つ、または現時点でのアクション(ブロッキングおよび非ブロッキングソケット)を実行する権利がありますが、事実は変わりません。 その間、接続をどれだけ開きたいか、実際にどのように開くか、かなりの時間がかかります。 そしてこれは悪いです。

しかし、良いニュースがあります。同時に多くのアクションを注文し、最初のアクションが終了するのを待つことができます。 同時に、アクションの数はそれぞれの実行時間に大きな影響を与えません。

これはすべて、イベントをサポートするライブラリを設計するように直接求めますが、それだけではありません。



混雑をリクエスト


ネットワークの使用には別のコストがかかります-各呼び出しには時間の価値があります。 楽しい時間をお過ごしください。 リソースの解放、オペレーティングシステムのキューイングなどに費やされます。 たとえば、1000 dnsリクエストを作成します。 各コールのコストを1ミリ秒(適切な時間、場合によってはそれ以上)にします。これは、コールでのみ1秒が失われることを意味します。 この時点で、同じスレッドで実行されているアプリケーションはFPSを介して「シンク」され、ユーザーにはフリーズが突然表示されます。

さらに、実際には、ドライバーは、システム内のすべてのアプリケーションに対して、毎秒50(上限からの数)要求を行います。

私はどこかでそうすることが正当であるかもしれないことを理解します(そして、これが起こるための設定があります)が、システムはリアルタイムアプリケーションのために開発されました、そして、これはそれらで受け入れられません。



タスク実行順序


OpenConnectionリクエストでは、ライブラリはメモリを割り当て、ジョブを順番に設定するだけです。 すべての操作は、ローカルアドレス空間とローカルストリームで行われます。これは、これらが高速であるためです。

実際の委任は、応答が呼び出されたときに発生します。応答が呼び出されると、タスクがスキャンされ、タイムアウトする前に次々に実行されます。

この例では、これにより、最初の50件の要求の後、接続の確立が開始され、1000のアドレスがすべて受信されるまで情報の交換を開始(または成功)することができます。

内部デバイスは、 イベント駆動型アーキテクチャと比較できますが、イベントの通知はオブザーバーパターンに従って発生しません。



優先タスク


WoWのようなオンラインゲームをプレイしましょう。 また、管理者がパッチを通じて新しいアイテムを販売したくないようにします。 何百万人ものプレイヤーが、神が禁じた剣を10個のオタクに、神が1000人の通行人を禁じる剣をダウンロードすることは、何の役に立つでしょうか?

同時に、戦闘がまだ完了していないときに、剣を戦闘に落としてください。 同じ音声通信をゲームに縫い付けます。

すぐにいくつかのデータストリームを同時に見ることができます。ボスへのダメージ、周囲の全員の生活レベル、動き、声、剣です。 (増加するボリュームでソートされたデータ)

移転の優先順位は次のとおりです:避難、生活水準、声、損害、剣。

ライブラリがそのような機能を提供していなければ、残念です。



関連タスク


この機能は、リリースでもアーキテクチャでも提供されていませんが、調和して適合しています。

互いのない剣、テクスチャ、モデル、アイコンの特性はあまり意味がありません。 しかし同時に、特性とアイコンを伝えることは論理的であり、モデルがロードされるのを待たずに武器を使用することを可能にします。

テクスチャとモデルは送信中に親の優先度を継承し、それらの優先度は相対オフセットによって与えられます。 転送がタイムリーに行われるように係数を選択する必要があります。



動的優先度


数ギガバイトの航海が終わり、システムでの優先度が低くなります。 そしてこの瞬間( 99.9% )に、数メガバイトの緊急データを転送する必要がありました。 想像上のギグが数十キロバイトになったという事実にもかかわらず。

ここでは、残りのデータ量とバッファリングされたデータ量に応じてタスクの優先度を変更することは非常に合理的です。

ライブラリ内の現在のソリューションが気に入らないので、それについて考え、改善できるかどうかを検討する必要があります。



記憶装置



データストレージモデル


複雑なシステムでは、異なる場所から1つのリソースにアクセスする必要がある場合があります。 たとえば、chat_listenerとattack_listenerはメッセージを送信したいと考えています。 さらに、それぞれに独自の接続セットがあります。

データの重複と非同期化を回避するために、ユーザーに与えられたオブジェクトのデータベースへのキーのストレージが使用されます( ここで最も近いのはBridgeで 、保存されたデータのみ )。

データベースは仮想ネットワークごとに1つあり(これが、同じネットワーク内のデータ操作がストリームに対して安全ではない理由です )、それに格納されているすべてのデータと同様に、 shared_self_controlledで管理されます



記憶に対する責任


タスクの性質上、ユーザーは割り当てられたメモリを完全に制御することはできません。

ライブラリの考え方-「出荷を行い、確実に届くようにする」ということは、あなたも従わなければならず、いつ来て削除する必要があるのか​​、やや毒です。

奇妙なことに、一般的な場合のライブラリは、オブジェクトをいつ正確に削除する必要があるのか​​もわかりません。 彼女は、転送する必要があること、この転送がいつ完了するかを知っていますが、その後削除する必要がありますか? オブジェクトのみがこれを知っています。 ( ああ、彼はこれを削除して使用しています



ガベージコレクター


起こっていることの本質を完全に反映していない大きな言葉。 しかし、リモートではそうです-オブジェクトを必要とするユーザーがなくなるとすぐに削除されます。 これはshared_ptrで保存できますが、オブジェクト自体がコンテナとオブジェクトの両方であることを除きます。

shared_self_conrolledは、文字通り次を意味します。 オブジェクトは(単純なself_controlledとは対照的に)共有することができ、(共有とは対照的に)いつ自己破壊する必要があるかを追跡する必要があります。

オブジェクトが転送されるとすぐに、ライブラリはそれを必要とせず、ユーザーのリストから自分自身を攻撃します。 それらがゼロになった場合、他の誰もオブジェクトにアクセスできません。それは必要ありません。



データ処理


遅延読み取り


数キロバイトのサイズのファイルをキロバイト接続で転送する必要があるとします。 数分間、メモリ内のファイルをアンロードする必要がありますか? またはそうであっても、ファイルの重量は数ギガバイトです。

この例の意味は、データを即座に処理する価値があるとは限らないということです。 今日は世界の終わりが来るかもしれないので、明日まで仕事を延期する方が良いでしょう? ;)



糸調子


機械をロープ(おもちゃなど)で引っ張りたい場合は、糸全体が引っ張られたときにのみ動きます。 力は、ある層から別の層に均等に伝達されます。 ある場所で剛性が他の場所よりも小さい場合-それは伸び、それ自体にすべての負担がかかります。

データハンドラが並んでいるとき、途中で何が起こるかについては興味がありません。 両端のトラフィックのみ。

圧縮されたデータを解凍する解凍ハンドラーがあり、クライアントには30バイトが必要です。 解凍されたとき、このボリュームを取得するために使用されたソースデータは5バイトのみでした。 教訓は、各リンクが次からどれだけ必要かを知っていることであり、それ以上のことはないということです。 これはライブラリに反映されます-すべての計算は要求に応じて実行されます。



キャッシング


数秒ごとに要求されるテラバイトのデータを処理する必要があるとします。 そのようなチェーンを作成することは論理的です:

読み込み=>計算=>一時ファイルへの保存=>一時ファイルからの読み込み=>転送

この場合、処理に必要なデータのみがメモリに保存され、ファイルに転送する準備ができます。

必要なデータ量を確認するために数秒待つのは愚かなことです。準備が必要です。

論理的な解決策は明らかです-空き時間にデータをドラッグして、計算と読み込みの段階で最小量、一時ファイルで最大量になるようにします。

このために、コンテナオプションがあります:最小化、最大化。 (これは、制限に違反した場合、リクエストの送信を停止することを意味します)

別の素晴らしい例はプロキシです。 データをダウンロードするよりも速くダウンロードする価値はありません。ローカルマシンのメモリ消費量が増加しますが、これは私たちには適していません。



おわりに



この投稿で、ライブラリを作成する理由となったアイデアと、それが私にとって競争力があると思われる理由を少しでもお見せできたことを願っています。 また、いくつかの向こう見ずな人たちは、ここで提案されているような素晴らしいもの(IMHO)の創造に参加したいと思っていると思います。

確かに、プロジェクトに隠されているすべてのアイデアではなく、潜在意識の中に入り込んで骨髄に隠れているものもあります。 これらは最も重要なものであり、頭に浮かびます。

「私たちは人のプロジェクトを覚えるのでなく、アイデアを覚えるように教えられています。なぜなら、人は弱く、捕まえられ、殺され、忘れられる可能性があるからです。 しかし、アイデアと400年後には世界が変わる可能性があります。” “ VはVendettaを意味します”

良い週末を。



All Articles