UiPath Blog
UiPathでは、ワークフロープロジェクトのメンテナンス性や可読性、開発効率の向上のため、処理ごとにワークフローファイルを分割することを推奨しています。
そして、ワークフロー分割の中核を担うのが、Invoke Workflow File(ワークフローファイルを呼び出し)アクティビティです。
本稿では、Invoke Workflow FileのIsolated(分離)プロパティ設定による動作の違いや、メリット・デメリットについて触れていきます。
1 Isolated(分離)プロパティの概要
Invoke Workflow Fileアクティビティには、Isolated(分離)というBoolean型(True / Falseの二択)のプロパティがあります。初期値はFalse、つまりプロセスを分離しない設定になっています。
これをTrueに設定すると、ワークフローの実行時に、呼び出し先のワークフローファイルの実行を別のプロセスで実行します。
「別のプロセス」と書くとエンジニア以外には馴染みがないかもしれませんので、少しプロセスについて記載します。
(UiPath Orchestratorの用語として「プロセス」がありますが、あちらはワークフローで作成された業務プロセスを指します。ここで説明するのはWindows OSにおける「プロセス」なので、別の概念になります)
「プロセス」は、Windows上でプログラムを実行する単位になります。プログラムが実行されている状態の単位とも言えます。プログラムとプロセスの違いは、1つのプログラムでも複数のプロセスが作れることです。
たとえば、「メモ帳」のプログラム(アプリケーション)そのものは、Windowsには通常、1つしかインストールされていません。
しかし、「メモ帳」の起動を2回行えば、「メモ帳」のプロセスは2つ作成されます。その結果、独立して個別に動作する2つの「メモ帳」の画面を操作することができます。これが「プログラム」と「プロセス」の違いです。
さて、UiPathでは、機能ごとにプロセスを分割しています。たとえば、StudioやRobotトレイは、それぞれ別のプロセスとなっています。
そして、ワークフロープロジェクトを実行する際は、UiPathのワークフロー実行機能として、UiPath.Executorというプロセスが起動されます。
UiPath.Executorは、前述のようにワークフロープロジェクトの実行を司るので、初期状態では1つしか起動しません。(そして、最初に起動したUiPath.Executorは、ワークフロープロジェクトの実行完了とともに終了されます)
少し前置きが長くなりましたが、Invoke Workflow FileのIsolatedプロパティをTrueにすると、それまで実行していたUiPath.Executorが、新しいUiPath.Executorのプロセスを作成し、そちらでInvoke Workflow Fileに設定されたワークフローファイル(.xamlファイル)を実行します。
【図:Isolatedを設定し、プロセスが分離されたUiPath.Executor】
次に、Isolated(分離)を行うことのメリットとデメリット・注意すべき点を説明します。
2 メリット
プロセスを分離することの最大のメリットは、メモリ不足や想定外のエラーなどで、UiPath.Executorのプロセスそのものが停止・異常終了した場合でも、呼び出し元のUiPath.Executorは異常を検知し、例外処理を行えることです。
大量のデータを扱う場合や、操作対象のアプリケーションが不安定ですべてのエラーハンドリングが困難な場合等、このオプションを使用することで該当箇所の実行を独立させ、問題が発生した際のリカバリーを容易にしたり、ワークフロー全体の失敗を防ぐことができます。
3 デメリット・注意すべき点
・システムへの負荷は上がります
システムへの負荷(CPU使用率やメモリ使用量の合計)は、単独のプロセスでの実行よりも増大します。
これは、プロセスを分離するため、単独のプロセスで処理するよりも連携・同期のコストが上がるためです。ただし、PCの性能にもよりますが、あまりに多く(10個を超えるような)のプロセスに分割するようなことがない限り、通常は意識する必要はありません。
・一部の引数の型は、プロセス分離の有無で動作が変わります
プロセスを分離している動作の性質上、ごく一部の型(変数・引数の型)の引数は、Invoke Workflow使用の有無で動作が変わります。これは、プロセスを跨いだ情報のやりとりをする機能を変数の型として持っているか、持っていないかによります。(専門的な用語だと、deserializeが可能でない型の場合の動作が異なります)
UiPathを使用していて、ユーザーの皆様がよく目にする多くの型(たとえばIntegerやStringなど)は、上記に当てはまりません。1つだけ例外として、DataTable型は、この点を意識する必要があります。
具体的な例を見てみましょう。
MainとDelFirstRowという2つのワークフローで構成されたプロジェクトを作ります。 Mainでは、テストデータをExcelファイルから読み取り、その行数を表示します。その後、Invoke Workflow FileでDelFirstRowに、読み込んだDataTableを渡します。最後に、もう一度行数の確認を行います。
DelFirstRowでは、In(受け取りのみ)で取得したDataTable型変数の、最初の行を削除しています。
さて、これを実行するとどうなるでしょうか。 Isolated(分離)なしと、ありの動作を比べてみます。
画像の実行結果のように、Isolatedなしだと、In設定(渡すだけ)に設定しているDataTableが、呼び出し先で行われた行削除の影響を受けていることがわかります。 そして、Isolatedありだと、DataTableの処理は呼び出し先の中だけで完結し、呼び出し元のDataTable型変数は影響を受けないため、行数に変化はありません。
これは、DataTable型の変数は、同じプロセス内でワークフローを跨いで引き渡した場合、(たとえIN/OUT指定ではなく、IN指定だけでも)メモリ上にある同じものを参照し続ける性質があるからです。
しかし、プロセスを跨いでしまうと、Windowsにより他のプロセスが使用しているメモリへのアクセスはできなくなります。(アクセスできてしまうと、他のソフトウェアの動作中にその中身を見れてしまい、脆弱性に繋がるため、Windowsがそのように作られています)
StringやIntegerなど、通常の変数の型であれば、値をそのままコピーするため、Invoke Workflowで引数として渡すとき、Isolatedプロパティの設定にかかわらず、呼び出し元とは独立して処理されます。
上記のDataTable型のような、複雑な動作になるケースは、少々、あいまいな表現になってしまいますが、UiPathで普通にワークフローを作成する上では他にないので、DataTable型をInvoke Workflowで引き渡すときだけ注意が必要、と覚えていただけると助かります。
また、DataTable型をInvoke Workflowで、In型の引数にする(つまり、呼び出し側で行うDataTableへの変更を、呼び出し元のワークフローに影響させたくない)ときは、DataTable型変数.Copy() を、引数として渡すことで、Isolated設定の有無にかかわらず(引き渡すのが作成されたコピーになるため)影響が発生しなくなります。
4 まとめ
Invoke Workflowを使用する際、Isolated(分離)プロパティの設定により、より安定したワークフローの構築が可能になります。
是非とも一度、お試しください。
Topics:
WorkflowProduct Support Engineer, UiPath