順番待ち Mendix 良いことかもしれない | Mendix

メインコンテンツへスキップ

順番待ち Mendix 良いことかもしれない

順番待ち Mendix 良いことかもしれない

バスや路面電車、電車で家に帰る列に並んでいるときや、昼食を買う列に並んでいるとき、あるいはカスタマーサービスで誰かが電話の列からあなたの電話に出るのを待っているときなど、待ち行列は時間の無駄であると見なされることが多い。お気に入りの小売業者/サプライヤーをここに入力してください>.

で Mendix アプリでは、ほとんどのアクションはシングルスレッドなので、たとえば、定義したアクションは最初から始まり、最後で終わり、その間は指定した順序で指定した操作に従います。これにより、定義した操作が期待どおりに実行されるかどうかをあまり心配する必要がなく、アクション内に依存関係がある場合はそれが何であるかを明確に確認できるため、物事がシンプルになります。

一方、キューは、プロセスの実行を複数のスレッドやノードに分散できるため、アプリにとって便利です。特定の作業を完了する必要がある場合、キューを使用すると、ジョブのさまざまな部分を同時に実行できるため、全体としてプロセスにかかる時間が短縮されます。では、どうすればそれができるのでしょうか。

これは、効率性に関するブログ投稿シリーズの3番目です。 Mendix アプリ。シリーズの最初の記事(健康と効率 Mendix)では、ローコードの効率を向上させる簡単な方法をいくつか紹介しました。そして2番目の(In Mendix 文字列の長さはどれくらいですか?)では、Javaアクションの使用が狭い場所でのパフォーマンス向上にどのように役立つかを示しました。今回は、 Mendix タスクキュー アプリの効率を高めるために使用できます。

タスクキュー

Mendix タスクキュー で紹介されました Mendix 9はProcess Queueマーケットプレイスモジュールの現代的な代替品として提供されており、その機能については十分に文書化されています。この記事では、特定の単純なユースケースを取り上げ、 タスクキュー することができます 必要なプロセスを実行するのにかかる時間を大幅に短縮するために使用される.

詳細な文書があります タスクキューページ それはあなたができることをカバーしています タスクキュー、そしてその実行方法についても説明します。これには、失敗したタスクの自動再試行や、特定の時間にタスクの実行を開始するスケジュール設定などの新しい機能も含まれます。覚えておくべき重要なポイントの 1 つは、自分で管理しない限り、プロセス内の「サブタスク」間に依存関係がないように注意する必要があることです。ここで示す使用例には単純な依存関係があり、それを制御する方法を設計しました。

大規模な削除

私のアプリは、定義された外部データソースからデータを取得するために使用されます ユーザーが要求すると、そのデータは簡単な分析にかけられ、ユーザーはそのデータをどのように使用するか決定することができます。ユーザーが満足して手元の作業を完了した時点で、 データを削除する必要があります。

テストアプリは、 タスクキュー 削除プロセスを高速化できます: GitHub – Adrian-Preston/QueueingCanBeAGoodThing

初期設定では、ドメイン モデルは自動削除用に構成されているため、ソース オブジェクトを削除すると、ツリーの下位に自動的にカスケードされ、関連付けられているすべてのオブジェクトが削除されます (ドメイン モデル内の関連付けボックスが赤で縁取られて強調表示されます)。これは、「孤立した」オブジェクトが残されるのを防ぐ安全なオプションであり、開発者がソースを削除するだけで、他のすべてがそれに続くことも意味します。ただし、シングル スレッド操作であるため、ツリーに大量のデータがある場合は時間がかかることがあります。

これは比較的単純なドメインモデルなので、特定のエンティティのオブジェクトを同時に安全に削除できることは簡単にわかります。つまり、ItemValue、ItemAttachment、ItemLink、AnalysedValue、AnalysedAttachment (セットXNUMX)は、同時に削除しても安全です。同様に、Item と AnalysedItem(セットXNUMX)は同時に削除できますが、 セットXNUMX すべて削除されました。最後に、Source、DocumentType、Documentを正しい順序で削除する必要があります。 セットXNUMX (NAIST) と セットXNUMX 削除されました。これらは先ほど述べた依存関係です。

それで、これはどうすればできるのでしょうか?

アプリの UI には、現在読み込まれているソースを一覧表示するページがあります。ユーザーはそこから削除するソースを特定し、その行の「ソースのスマート削除」ボタンを押します。

これは、「ACT_SmartDeletion」と呼ばれるナノフローを呼び出します。このナノフローには、2 つの主なタスクがあります。1 つ目は、バックグラウンドで削除プロセスを開始すること、2 つ目は、タスクが完了したことを示すソース レコードがデータベースから消えるまで待機することです。

ナノフローは「SUB_StartSmartDeletion」と呼ばれるマイクロフローを呼び出し、これは各エンティティタイプごとにサブマイクロフローを呼び出します。 セットXNUMX ただし、これらはそれぞれタスクキューに入れて呼び出されるため、直接実行されるのではなく、バックグラウンドで実行されるようにキューに入れられるだけです。また、サブマイクロフローごとに受信する特別な DeletionControl オブジェクトも作成します。これについては後ほど詳しく説明します。このマイクロフローが終了すると、ナノフローに戻ります。

次に、ナノフローはループに入り、ソース レコードがデータベース内にまだ存在するかどうかを確認します。ソース レコードが存在する間、ナノフローは短時間停止してから再度確認します。ソース レコードがデータベース内になくなると、ナノフローはユーザーに通知して完了します。

5 つのサブマイクロフローはそれぞれ同じです (1 つにいくつかの追加コードがある点を除く)。サブマイクロフローは、特定の種類のエンティティのソースのすべてのレコードを削除し、最後に上記の DeletionControl オブジェクトを削除します。

'SUB_DeleteItemValue'の追加コードは、 セットXNUMX is 完了したら(すべてのDeletionControlオブジェクトが削除されているか確認する)、同じサブマイクロフローを開始します。 タスクキュー エンティティの削除を実行するには セットXNUMX、 そうするとき セットXNUMX 完成されました セットXNUMX 削除は同じメカニズムを使用して自動的に開始されます。

同様に「SUB_DeleteItem」は、すべてのアイテムを削除したら、 セットXNUMX 完了して最後に Source レコードを削除し、プロセスを完了します。DocumentType レコードと Document レコードの数は少ないため、ドメイン モデルの「削除時」動作を使用して削除します。

SUB_DeleteItem プロセスを完了するためにソースを削除する追加コード

比較するとどうでしょうか?

テスト アプリにはソースに「ソースの簡単な削除」ボタンがあり、これはソースを直接削除し、依存オブジェクトも削除されるようにドメイン モデルを残します。したがって、テスト データ セットに対して、簡単な削除またはスマート削除のいずれかを実行できます。また、アプリには、新しいテスト データ セットの作成、テスト データ セットのエクスポート、テスト データ セットの再インポートの機能があります。このように、 アプリでは新しいセットの作成が可能で、エクスポート/インポートも可能なので、同じデータに対してシンプル削除とスマート削除のオプションを繰り返し使用できます。.

アプリのリソース ディレクトリに「Source-36e63c07–9a8a-4c94–8f87–0fbf9b7dd39f」というテスト データ セットが含まれています。これは、削除を比較するために私のマシンで使用されているセットです。これを使用することも、独自のセットを作成することもできます。

テストアプリを実行しました Mendix 9.18.0 で、ローカルの Postgres 10 データベースにアクセスするように構成されています。各タイプの削除をテストする前に、アプリを最初から作成しました。次に、テスト データセットをインポートし、削除を XNUMX 回実行しました。XNUMX 回のうち、最良の結果と最悪の結果は無視し、残りの XNUMX つのタイミングの平均を算出しました。

それで結果はどうだったでしょうか?シンプル削除オプションでは平均して 163.9 スマート削除オプションでは平均で 29.4 秒 — 5分の1未満 シンプル削除にかかる経過時間。ユーザーが削除が完了するまで待機している場合、これは価値のある節約のように思えます。

この操作でユーザー エクスペリエンスを向上させる方法は他にもあります。たとえば、ソース レコードにブール フラグを設定してソースを削除済みとしてマークし、そのようにマークされたソース レコードとその従属レコードを削除する、別の定期的なスケジュールされたイベント プロセスを用意することができます。問題に対する解決策は 1 つだけではありません。

また、1 人のユーザーに対して複数のスレッドが集中して動作していると、他のユーザーのアプリの速度が低下する可能性があることにも留意する必要があります。そのため、正確なユースケースのニーズとソリューションの効果を十分に理解し、バランスを取る必要があります。

水平方向にスケールする本番環境がある場合、 タスクキュー クラスター内の利用可能なノード全体に分散されるため、さらに時間を節約できる可能性があります (ただし、ここで紹介するシナリオは、常に共有リソースであるデータベースに焦点を当てています)。

もう一つ

現状では、ユーザーの時間を大幅に節約でき、アプリ使用時のエクスペリエンスが向上することを期待しています。しかし、1 つ欠けているものがあります。

ドメインモデルでは、Item、ItemValue、ItemAttachment、ItemLink、AnaysedItem、AnalysedValue、AnalysedAttachment 間の関連付けに自動削除オプションがまだ設定されています。スマート削除オプションを使用すると、ドメインモデルでこれらのオブジェクトを自動的に削除しても、対象データがすでに削除されているため、実際には何も削除されません。ただし、 Mendix ランタイムは削除するレコードがあるかどうかを確認する必要があり、それには時間がかかります。

最後に、ドメイン モデルから自動削除オプションを削除し、スマート削除を再実行して、その効果を確認します。

不要な自動削除オプションを削除したドメインモデル

この変更を行った後、以前と同様にスマート削除を5回実行したところ、平均経過時間は 10.0 秒と比較して 29.4 秒です。これで、通常の経過時間が短縮されました。 163 秒単位で 10 数秒です。これは私にとっては勝利のように思えますが、ソースを削除しても依存関係がカスケードダウンしなくなることに注意してください。そのため、アプリ内の他の場所でこのデータに削除を適用する必要がある場合は、そのためのソリューションも設計する必要があります。

要約で

使い方 タスクキュー 適切なユースケースに慎重に適用すると、経過時間のパフォーマンスを大幅に向上できます。この例では、テスト結果から、ユーザーにとって大幅な節約が実現していることが示されています。

走行距離は異なる場合があります

おそらく言う必要はないでしょうが、この手法 (大規模な削除だけでなく、あらゆる種類のプロセス) を使用する利点は、実行される操作とドメイン モデルの複雑さ、環境内の予備リソースの量、およびモデルをどの程度複雑にしたいかによって大きく異なります。もう一度、コードを読みやすく保守しやすい状態に保つことについての以前のブログでのコメントを参照してください。

さらに、2 人以上のユーザーが同時にソース レコードを削除すると、キュー リソースが共有され、各ユーザーの節約額が少なくなる可能性があります。

私はこのようなテクニックを実際の生産環境(Mendix 9 では ProcessQueue Marketplace モジュールを使用しました) が、私を驚かせ、プロダクト オーナーを喜ばせるほどのパフォーマンス向上を実現しました。ぜひブランチを作成して試してみてください。

楽しい待ち行列を!

言語を選択してください