注: 以下の翻訳の正確性は検証されていません。AIPを利用して英語版の原文から機械的に翻訳されたものです。
ユーザー編集は、オントロジー・マネージャーの Datasources タブにある Edits トグルを使用して有効化および無効化できます。以下のスクリーンショットに示すようになります。
このセクションでは、オントロジーがアクションを使ってオブジェクトの編集を管理する方法について説明します。
アクションがオブジェクト、リンク・インスタンス、またはオブジェクト・セットに適用されると、データ変更ロジックはオブジェクト・データベースのインデックスに直ちに適用され、定期的に Funnel が所有および管理する Foundry データセットの形で永続ストアにフラッシュされます。詳細は、persistent storage of user edits のドキュメントを参照してください。
アクションがトリガーされると、アクションサービスは Funnel サービスに変更指示を送信します。この指示は、同時ユーザー編集をサポートするオフセット追跡を持つ Funnel 管理キューに格納されます。Object Storage V2 は、オブジェクト・タイプや多対多リンク・タイプに関連する結合テーブルを持つすべてのオフセットを追跡します。オフセットはオブジェクト・データベースのライブ・インデックスデータに適用され、オントロジー・クエリの一部として行われるオブジェクト・リードがユーザー変更後に行われる場合、オブジェクト・リードにはユーザー編集が含まれることが保証されます。
ユーザー編集は、入力データソースよりも優先されることが、Resolving conflicts セクションでさらに説明されています。したがって、ユーザー編集が含まれるデータを更新するには、ユーザー編集も行う必要があります。単一のユーザー編集や削除を元に戻すメカニズムはありませんが、代わりに追加のユーザー編集(例:オブジェクト・アクション)を行ってオブジェクトを更新したり、再作成したりすることができます。
特定の状況下では、すべてのオブジェクト・インスタンスの状態を入力データソースと同じ状態にリセットするために、すべての既存のユーザー編集を破棄することが望ましい場合があります。例えば、オブジェクト・タイプを本番環境でリリースする前に、オブジェクト・タイプのテスト中に適用されたすべてのユーザー編集を削除することが考えられます。
Object Storage V2 は、ユーザー編集を移行するための schema migration framework を提供しています。"drop all edits" インストラクションを使って、オブジェクト・タイプの既存のユーザー編集をすべて破棄することができます。この移行指示は、オントロジー・マネージャーの Datasources タブの Edits セクションにある Delete edits ボタンをクリックすることで適用できます。
Object Storage V1 (Phonograph) は、スキーマ移行のサポートがありませんが、オブジェクト・タイプ定義から書き戻しデータセット構成を削除すると、既存のユーザー編集がすべて削除されるため、回避策として使用できます。
アクションを適用する過程で、オブジェクト・タイプのメタデータ情報やオブジェクト・インスタンス・データが、アクションの検証、Functions、アクション side effects などの目的でロードされます。オブジェクト・インスタンスは、アクションを適用する過程で変更される場合があり、トランザクション性を保証することが重要です(例:アクションをオブジェクト・インスタンスの誤ったバージョンに適用するなどのデータ正確性の問題を避けるため)。
オントロジーには、オブジェクト・タイプとオブジェクト・インスタンスのバージョンの両方のバージョン一貫性をチェックするメカニズムが含まれており、Object Storage V1 (Phonograph) と Object Storage V2 の間で異なる動作があります。
以下のシナリオを考えてみましょう。ユーザーは、Action form でバージョン {V1, V2, V3, ...}
のオブジェクト・インスタンス・パラメーターをロードします。フロントエンドの消費者アプリケーションは、これらのオブジェクト・パラメーターを持つアクションサーバーの /apply
エンドポイントを呼び出しますが、そのリクエストにはバージョンが含まれません。このリクエストを受け取ったアクションサーバーは、/apply
エンドポイント内でバージョン {V1', V2', V3', ...}
のオブジェクトをロードします。フロントエンドでロードされたバージョン {V1, V2, V3, ...}
と、アクションサーバーによってロードされたバージョン {V1', V2', V3', ...}
が常に同じであることを保証するものではありません。
Object Storage V1 (Phonograph) では、アクションサーバーはロードされたオブジェクトのバージョンを追跡し、アクションの実行中にキャッシュから同じバージョンをロードします。ユーザー編集が Object Storage V1 (Phonograph) に適用されると、リクエストにオブジェクトのバージョンが含まれます。Object Storage V1 (Phonograph) は、オブジェクトのバージョンが変更されたかどうかをチェックし、変更が検出された場合には StaleObject
エラーをスローします。
これらのチェックは、アクションサーバー内で一般的な整合性を保証します。たとえば、Object Storage V1 は、アクションが同期 webhook を生成し、実行し、検証し、オブジェクトの同じバージョンに編集を適用することを保証しています。ただし、プロパティレベルでのオブジェクトの変更はチェックされないため、オブジェクトの無関係なプロパティに対するユーザー編集が StaleObject
の競合を引き起こす可能性があります。
Object Storage V2 では、アクションサーバーは Funnel サービスにユーザー編集を投稿する前に、オブジェクトのバージョンチェックを独自に実行しますが、Object Storage V1 (Phonograph) で収集されるバージョンのサブセットに対して限定的なバージョンチェックを行います。
アクションサーバーは、編集を生成するために直接使用されるオブジェクトのバージョンのみをチェックします。例えば、あるオブジェクト A
のプロパティがオブジェクト B
にコピーされたバージョンなど、これらのバージョンは、編集されたオブジェクトバージョンとのみ比較されます。
この挙動は、StaleObject
の競合の頻度を減らしますが、OSv2 での保証が弱くなる結果となります。Object Storage V2 では、アクションサービスは常にアクション /apply
中に同じバージョンのオブジェクトをロードしますが、編集生成以外のオブジェクトの読み取りがアクションの過程で変更されていないことを保証しません。
アクションタイプが OSv1 と OSv2 の両方でオブジェクトを同時に変更する場合、「クロスバックエンド」と見なされます。このような場合、アクションサービスは次のオブジェクトに対してチェックを実行します。
オブジェクトデータベースのすべてのインデックスデータは、一時的なものと見なされ、オントロジーデータを他の方法で永続的に保存する必要があります。同様に、アクションを介したユーザー編集も永続的に保存する必要があります。オブジェクトタイプをバックアップする Foundry データソースは、Foundry データセット、制限付きビューなどの形で既に永続的に保存されています。
Funnel pipelines documentation で説明されているように、Funnel サービスは、データソースからのデータとユーザー編集を組み合わせたマージされたデータセットを含む、いくつかの Foundry データセットを所有および管理しています。マージされたデータセットは自動的に構築され、キューに保存されたユーザー編集が Foundry で永続的に保存され、キューが大きくなりすぎるのを防ぐためにキューが空になることが保証されます。デフォルトでは、このビルドジョブは次のタイミングでトリガーされます。
Foundry オントロジーのオブジェクト・インスタンスは、入力データソースとユーザー編集の両方によって作成および変更されることがあります。特定の主キー値を持つ単一のオブジェクト・インスタンス(つまり、行またはオブジェクト)が入力データソースとユーザー編集の両方からデータを受け取る場合、これらの受け取った値は、競合解決戦略 を使って透過的に解決する必要があります。 対立解決のための2つの戦略があります。
この戦略では、オブジェクトインスタンスの最終状態は、同じオブジェクトインスタンスに対するデータソースの今後の更新に関係なく、それに適用されたユーザー編集によって常に決定されます。
ユーザー編集とデータソースの更新に基づいてオブジェクトインスタンスの最新の状態を決定するための下のフローチャートを参照してください。
以下の表は、特定のオブジェクトインスタンスが「ユーザー編集が常に勝つ」対立解決戦略に従って、ユーザー編集と入力データソースの更新を受け取った後にどのように更新されるかを示しています。
時間 | 現在のデータソースの行の状態 | ユーザー編集 | 最終オブジェクト状態 | 説明 |
---|---|---|---|---|
T0 | columns = {pk_column = pk1, col1 = val1, col2 = val2} | properties = {pk_column = pk1, col1 = val1, col2 = val2}, deleted = false | ||
T1 | columns = {} | properties = {}, deleted = true | データソースから行が消え、オブジェクトインスタンスはもはや Foundry オントロジーに存在しない | |
T2 | columns = {pk_column = pk1, col1 = val1, col2 = val2} | properties = {pk_column = pk1, col1 = val1, col2 = val2}, deleted = false | データソースに同じ行が再表示される | |
T3 | columns = {pk_column = pk1, col1 = val1, col2 = val2} | オブジェクトの変更: properties = {pk_column = pk1, col2 = newVal2} | properties = {pk_column = pk1, col1 = val1, col2 = newVal2}, deleted = false | ユーザーは Modify object アクションを実行する |
T4 | columns = {} | properties = {}, deleted = true | データソースから再び行が消え、オブジェクトインスタンスはもはや Foundry オントロジーに存在しない | |
T5 | columns = {pk_column = pk1, col1 = val1, col2 = val2} | properties = {pk_column = pk1, col1 = val1, col2 = newVal2}, deleted = false | データソースに同じ行が再表示され、前のユーザー編集が行が再表示されたときにオブジェクトインスタンスに適用される | |
T6 | columns = {pk_column = pk1, col1 = newVal1, col2 = val2} | properties = {pk_column = pk1, col1 = newVal1, col2 = newVal2}, deleted = false | 編集されていないプロパティ(col1 )が入力データソースからデータ更新を受け取り、オブジェクトインスタンスに適用される | |
T7 | columns = {pk_column = pk1, col1 = newVal1, col2 = val2} | オブジェクトの削除 | properties = {}, deleted = true | ユーザーは Delete object アクションを実行し、オブジェクトインスタンスはもはや Foundry オントロジーに存在しない |
T8 | columns = {pk_column = pk1, col1 = newVal1, col2 = val2, col3 = null} | properties = {}, deleted = true | ||
T9 | columns = {pk_column = pk1, col1 = newVal1, col2 = val2, col3 = null} | オブジェクトの作成: properties = {pk_column = pk1, col3 = val3} | properties = {pk_column = pk1, col1 = null, col2 = null, col3 = val3}, deleted = false | ユーザーは Create object アクションを実行する |
T10 | columns = {pk_column = pk1, col1 = newVal1, col2 = newVal2, col3 = newVal3} | properties = {pk_column = pk1, col1 = null, col2 = null, col3 = val3}, deleted = false | 入力データソースで col3 が更新されるが、以前の Create object アクションのためにオブジェクトインスタンスの最終状態には考慮されなくなる | |
T11 | columns = {pk_column = pk1, col1 = newVal1, col2 = newVal2, col3 = newVal3} | オブジェクトの変更: properties = {pk_column = pk1, col2 = newVal22} | properties = {pk_column = pk1, col1 = null, col2 = newVal22, col3 = val3}, deleted = false | ユーザーは Modify object アクションを実行する |
T12 | columns = {} | properties = {pk_column = pk1, col1 = null, col2 = newVal22, col3 = val3}, deleted = false | データソースから行が消えるが、オブジェクトインスタンスはユーザー編集で最後に作成されたため、Foundry オントロジーにまだ存在する | |
T13 | columns = {pk_column = pk1, col1 = newVal1, col2 = newVal2, col3 = newVal3} | オブジェクトの削除 | properties = {}, deleted = true | 行が再表示されるが、ユーザーは Delete object アクションを実行し、オブジェクトインスタンスが削除される |
T14 | columns = {pk_column = pk1, col1 = newVal1, col2 = newVal2, col3 = newVal3} | オブジェクトの変更: properties = {pk_column = pk1, col2 = newVal2, col3 = val3} | properties = {}, deleted = true | ユーザーは削除されたオブジェクトインスタンスに Modify object アクションを実行する。すべての Modify object アクション呼び出しが失敗します |
この機能は、現在すべてのエンロールメントで利用できません。
この戦略では、ユーザー編集は条件付きで適用されます。つまり、ユーザー編集は、データソースからのタイムスタンプ値が与えられたオブジェクトインスタンスよりも新しい場合にのみ適用されます。
対立解決戦略は、オブジェクトタイプレベルで設定され、単一の入力データソースを持つ OSv2 オブジェクトタイプでのみサポートされます。
ユーザーは、オントロジーマネージャーの Datasources
セクションでこのオプションを設定できます。最新の値を適用する
オプションでは、オブジェクトタイプにタイムスタンプタイプのプロパティを含める必要があります。日付プロパティタイプは、このオプションでは機能しません。タイムスタンププロパティは、ユーザー編集が適用されるべきかどうかを決定するための比較に使用されます。
オブジェクトタイプに対して 最新の値を適用する
対立解決戦略が保存されると、すぐに_今後の_ユーザー編集が条件付きで適用されます。これは、オブジェクトインスタンスに存在するタイムスタンプと、適用された最新のユーザー編集のタイムスタンプを比較することで機能します。オブジェクトのタイムスタンプがユーザー編集時間よりも古い場合にはユーザー編集が適用され、そうでない場合には無視されます。
ユーザー編集とデータソースの更新に基づいてオブジェクトインスタンスの最新の状態を決定するための、下の更新されたフローチャートを参照してください。
以下の例は、この挙動を説明しています。チケット
オブジェクトタイプの3つのオブジェクトインスタンスが以下のデータであると仮定します。ここで、最新の値を適用する
オプションが有効になっており、チケットの優先度を P0
に変更するアクションタイプ Change Priority
があります。
チケットID | タイトル | タイムスタンプ | 優先度 |
---|---|---|---|
101 | Ticket One | 2010年1月1日 | P1 |
102 | Ticket Two | 2050年1月1日 | P2 |
103 | Ticket Three | P2 |
Change Priority
アクションが Ticket One に適用された場合、ユーザー編集がデータソースからのタイムスタンプ値の後に来るため、優先度は P0
に設定されます。Change Priority
アクションが Ticket Two に適用された場合、ユーザー編集がデータソースからのタイムスタンプ値の前に来るため、優先度は P2
のままです。Change Priority
アクションが Ticket Three に適用された場合、データソースからのタイムスタンプ値が存在しない場合は常にユーザー編集が適用されるため、優先度は P0
に設定されます。オントロジーは、入力データソースからのタイムスタンプとユーザー編集の適用時間との間でのみタイムスタンプを比較することに注意してください。ユーザーがユーザー編集を介してタイムスタンププロパティを変更しても、条件付きの比較は入力データソースからのタイムスタンプとユーザー編集の適用時間の間でのみ行われます。
この挙動の結果として、タイムスタンププロパティは入力データソースのタイムスタンプ列によってバックアップされなければなりません。ソースシステムがデータフィードの更新時間を示すタイムスタンプ値を提供しない場合、データパイプライン内の入力データソースのタイムスタンプ列を変更できます。
上記のチケットの例に戻ります。以下の表を考慮してください。
チケットID | タイトル | タイムスタンプ | 優先度 |
---|---|---|---|
101 | Ticket One | 2010年1月1日 | P1 |
アクションタイプ Change Timestamp
が使われて、上記のチケットのタイムスタンプを 2050年1月1日
に変更すると仮定します。
チケットID | タイトル | タイムスタンプ | 優先度 |
---|---|---|---|
101 | Ticket One | P1 |
これで、Ticket One に Change Priority
アクションが適用された場合、優先度はまだ P0
に設定されます。
オブジェクトインスタンスに表示されるタイムスタンプに関わらず、比較は入力データソースからのタイムスタンプとユーザー編集の適用時間の間でのみ行われます。