System.Workflow.Activities.EventDeliveryFailedException を防止する Part 2

こんにちは SharePoint サポートの森 健吾 (kenmori) です。

今回の投稿では、2011 年 4 月に私が投稿した記事 (System.Workflow.Activities.EventDeliveryFailedException を防止する) の続編ではありますが同一の現象ではなく、SharePoint 2010 の 2012 年 12 月の CU を含む、それまでの修正プログラムにて、類似事象が複数回にわたって、いくつか修正されてきていることをお伝えする内容です。

今回の現象の診断ログ抜粋 ( 英語環境 )

EngineRunWorkflow: System.Workflow.Activities.EventDeliveryFailedException: Event "OnTaskChanged" on interface type "Microsoft.SharePoint.Workflow.ITaskService" for instance id "8df07135-0710-4056-a286-49244a0bbb61" cannot be delivered. --->
System.Workflow.Runtime.QueueException: Event Queue operation failed with MessageQueueErrorCode QueueNotFound for queue 'Message Properties Interface
Type:Microsoft.SharePoint.Workflow.ITaskService Method Name:OnTaskChanged CorrelationValues: 743944d4-f704-4731-9bca-ce47b36cf6b3 '.
at System.Workflow.Runtime.WorkflowQueuingService.GetQueue(IComparable queueID)
at System.Workflow.Runtime.WorkflowQueuingService.EnqueueEvent(IComparablequeueName, Object item)
at System.Workflow.Runtime.WorkflowExecutor.EnqueueItem(IComparable queueName,Object item, IPendingWork pendingWork, Object workItem)
at System.Workflow.Runtime.WorkflowInstance.EnqueueItem(IComparable queueName,Object item, IPendingWork pendingWork, Object workItem)
at System.Workflow.Activities.WorkflowMessageEventHandler.EventHandler(Object sender, ExternalDataEventArgs eventArgs)
--- End of inner exception stack trace ---
at System.Workflow.Activities.WorkflowMessageEventHandler.EventHandler(Object sender, ExternalDataEventArgs eventArgs)
at Microsoft.SharePoint.Workflow.SPWinOETaskService.CallEventHandler(Type eventType, String eventName, Object[] eventData, SPWorkflow workflow, String
identity, IPendingWork workHandler, Object workItem)
at Microsoft.SharePoint.Workflow.SPWorkflowExternalDataExchangeService.RunEvent(SPWorkflowEvent workflowEvent, SPWorkflow workflow, IPendingWork workHandler, SPPendingWork eventDequeue)
at Microsoft.SharePoint.Workflow.SPWinOeHostServices.Send(SPWorkflow workflow, SPWinOeWorkflow winoeworkflow, SPWorkflowEvent e)
at Microsoft.SharePoint.Workflow.SPWinOeEngine.RunWorkflow(SPWorkflowHostService host, SPWorkflow workflow, Collection`1 events, TimeSpan timeOut)

 

EventDeliveryFailedException について

ワークフローでイベント通知が失敗した場合、上記のような診断ログが記録され、画面で承認等の操作を実行してもワークフローが再開されなくなってしまいます。

この現象に陥った場合は、ユーザー操作による承認等のイベント通知がワークフロー側に正常に通知されなくなりますため、一般的にはワークフローを一度終了し、再度ワークフローを最初から起動する必要があります。
さらに、この現象はワークフローの状態が “進行中” のまま表示される傾向があり、ワークフローを何度承認しても承認されないなどの現象ではじめて気づくことになります。

ただし、今回の QueueException の場合、メモリ上にワークフロー インスタンスが残ることよって発生するものであることが確認できております。そのため、スケジュールによるアプリケーションプールの自動リサイクル ( 既定では 1 日に 1 ) またはアプリケーションプールを明示的に再起動した後は、承認プロセスが正常に継続する場合があります。

 

技術的な詳細について

Windows Workflow Foundation の基盤に基づき、SharePoint ワークフローもワークフロー ランタイムと呼ばれるワークフローを動作させるための基盤と、ワークフローの処理自体を表すインスタンスがそれぞれ役割を分担する仕組みです。

ワークフロー インスタンスから外部メソッド (SharePoint に対する処理) を呼ぶ種類や外部からのイベント (SharePoint からのイベント) を受け取る種類のなどの組み込みのアクティビティを使用する場合、ワークフロー インスタンスとワークフロー ランタイムの間で通信が生じます。

SharePoint が公開している外部イベント受信型 (HandleExternalEventActivity より派生) の組み込みのアクティビティ (OnWorkflowItemChanged, OnTaskChanged など) の一般的な動作として、ワークフローの初期化時に、ランタイム側に対してワークフローが使用するイベント レシーバーをアイテムやタスク等に追加させます。

該当のアイテムやタスクなどが更新された際には、ワークフローを対象としたイベント レシーバーが起動してワークフロー ランタイムがメッセージ キュー経由で、ワークフロー インスタンスをロードおよび再開するよう通知する動作となります。

上記の前提において、ワークフローの EventDeliveryFailedException は、SharePoint 側で検知したイベント通知をワークフロー ランタイム側からアクティビティ側に通信する際の処理のどこかで失敗したことを示すエラーです。
この例外はイベント伝達処理実行時に生成される様々な内部例外をラップしてスローするための形式的な例外であり、過去事例を確認する限り具体的なエラー内容を示す内部例外にはいくつかの種類があることを確認しています。

例えば、前回ご紹介した EventDeliveryFailedException は内部例外が System.NullReferenceException であり、イベントがワークフロー インスタンス側に伝達されて処理されはじめる際に発生しているものです。
今回ご紹介する EventDeliveryFailedException の内部例外はSystem.Workflow.Runtime.QueueException であり、Windows Workflow Foundation 内部でメッセージ キューを経由した通知に失敗したという旨となります。

 

EventDeliveryFailedException (内部エラー QueueException ) について

特定の条件下において、ワークフロー インスタンスのアンロードが実施されない条件が存在していました。

すでにロード済みのワークフロー インスタンスがある状況においては、ワークフロー インスタンスがメモリ内にロードされたままの状態となるため、メッセージ キューがイベントを受信してワークフロー インスタンスをロードするといった動作を実行できない状態となります。

この結果、アプリケーション プールのリサイクルや SharePoint Timer サービス (OWSTIMER.EXE) などメモリ内にロードされたワークフロー インスタンスをアンロードしない限り、イベントの伝達が正常に行われない現象が発生する可能性がありました。

例えば、2012 年 12 月 CU で修正された内容としては、何らかの要因によってイベント伝達エラーが発生した際にインスタンスがリークする動作に対する修正が含まれます。
このことにより、以降はあとで実行されるユーザー イベントを受け付けない現象に至っていました。
該当パッチの適用後は、仮に最初何らかの要因でイベント伝達時のエラーが発生した場合においても、次に発生するイベントでは QueueException が再発することなく処理されます。
復旧にワーカー プロセスまたはワークフロー再起動なしに以降のワークフローのイベント通知が継続するように変更されています。

 

対処策

上記の通り、2012 年 12 月の累積的な更新プログラムを含むそれまでの更新プログラムに複数回にわたり、ワークフロー インスタンスのアンロード漏れにより、ワークフローが次のステップに進まなくなる現象が修正されています。

本修正プログラムでは、上述の通りメモリ内にロードされたワークフロー インスタンスが適切にアンロードされない動作を解消する修正が実施されています。

タイトル : SharePoint Server 2010 の累積的な更新プログラム パッケージ (SharePoint サーバー パッケージ) の説明: 2012 年 12 月 22日
アドレス : https://support.microsoft.com/kb/2596955

上記サイトより、現象発生するようであれば、修正プログラムを入手いただき、経過観察していただけますと幸いです。

タイトル : 2012 年 12 月の CU がリリースされました
アドレス : https://blogs.technet.com/b/sharepoint_support/archive/2012/12/13/2012-12-cu.aspx

今回の投稿は以上になります。