Project

General

Profile

Bug(バグ) #2911

プラグイン無効時にデータ削除を伴う操作でエラーやデータ不整合が発生する

Added by pnetan   over 7 years ago. Updated over 2 years ago.

Status:
Won't fix(対応せず)
Priority:
High(高め)
Assignee:
Target version:
Start date:
2012-03-30
Due date:
% Done:

0%

3.6 で発生するか:
Yes (はい)
3.8 で発生するか:
Yes (はい)

Description

Overview (現象)

プラグイン無効時に退会などのデータ削除を伴う処理がエラーとなり操作できない場合がある。

例:

  • opCommunityTopicPlugin 無効時、退会処理を行うと500エラーとなり退会できない
  • opCommunityTopicPlugin 無効時、コミュニティ削除処理を行うと500エラーとなり削除できない
  • opCommunityTopicPlugin 無効時、画像削除を行うと500エラーとなり削除できない(プロフィール画像や日記画像などコミュニティトピックと関係のない画像であってもエラーになる)

バンドルプラグインでは opCommunityTopicPlugin だけであるが、schema.yml で actAs を使ってプラグイン内のクラスを指定している場合、同様の問題が発生する。

また、プラグイン無効時にはエラーとはならないがデータ不整合が発生し、再有効化後に問題が発生する場合がある。

例:

  • opIntroFriendPlugin 無効化中に紹介文の存在するフレンド関係を削除し、再度 opIntroFriendPlugin を有効化すると、フレンドではないメンバーの紹介文が削除されておらず表示されてしまう

Causes (原因)

Doctrine により自動生成されるモデルはプラグインの有効・無効を考慮しないため、無効なプラグインのモデルを利用するコードが生成される。例として relation 関係のあるモデルの削除処理の過程で利用される(削除以外の処理で利用されるかどうかの網羅的な調査はできていない)。これにより単純な onDelete: cascade などのデータ整合性を保つための処理がプラグイン無効時にも動作するというメリット(?)はある。

一方、無効なプラグイン内のファイルに含まれるクラスライブラリはオートロードの対象から外れるため、それを呼び出すコードを実行すると Fatal Error となり PHP の実行は停止され、クライアントへは結果として 500 エラーが返される。

opCommunityPlugin のように schema.yml 内で actAs にプラグイン内のクラスが指定されている場合、これに該当し関連するモデル(この例では Member, Community, File)の削除処理において Fatal Error が発生する。

また、プラグイン内でイベントハンドラによりコア側や他プラグインの動作タイミングでデータ更新をしている場合には、プラグイン無効時にイベントハンドラが呼び出されないため、データの不整合が発生する。opIntroFriendPlugin はフレンド削除のタイミングで、op_action.post_execute_friend_unlink イベントを利用し(onDelete: cascade のようなDB上の制約を使わずに)データ削除を行なっているため、このケースに該当する。

Way to fix (修正内容)

プラグインの有効・無効の切り替え機能を完全に機能させる前提での修正が難しいため、管理者がそのことを理解した上でこの機能を利用できるように画面上に注意文を追加する対応とする。

機能自体を削除することも検討したが、問題なく有効・無効を切り替えられるプラグインも多いため、安定版での機能削除は不適当と判断した。削除するのであれば別途 Enhancement チケットを作成して開発版のみで対応すべきと考える。


補足として、プラグインの有効・無効の切り替え機能を完全に機能させることが難しい理由を以下に記す。

プラグインを 有効 → 無効 → 有効 と切り替えた際に正常な動作を保証するのが困難で、無効な状態の際にデータの更新処理をどのようにおこなうか(おこなわないか)が課題となる。

データの整合性を保つためには無効なプラグインに関するデータの更新処理をおこなう必要があり、そのためにはプラグイン下のライブラリやDB上のテーブル間の制約を動作させる必要がある。ただし、データの整合性を保つための機能だけを動作させるというのはコア側から一定のルールで切り分けができるものではなく、必要以上に動作してしまう部分が出てくる懸念があるため、各プラグインでもなんらかの実装を合わせてする必要がある可能性が高い。例えば、プラグイン内のイベントハンドラによる処理などは基本的にどんな処理でも書ける仕様であるため、コア側で無効時にどの処理が必要かを判別する術がない。逆にコア側のオートロードの仕組みを変えない限りはプラグイン側だけで解決できる問題でもない。なんとか制御する仕組みが作れたとしてもコア、プラグイン共に変更は大規模となりプラグイン側の後方互換性を損なう恐れもある。

データの整合性を諦めて無効なプラグインのデータの更新処理はおこなわない方針を目指したとしても、少なくとも Doctrine のモデル、DB テーブルの外部キー制約を改変する必要がありこれだけでも簡単ではない。特に外部キーは再有効化時にデータ不整合で戻せない可能性もある。そもそもこの方針が上手く行ったところで再有効化時に正常動作する保証はないため、プラグインの有効・無効切り替えが正常動作しているとは言い難い。

参考情報

http://sns.openpne.jp/communityTopic/8139 より転記

(1) OpenPNEのバージョン
OpenPNE 3.6

(2) サーバ情報
CentOS 5.7
PHP 5.3.3
MySQL 5.0

(3) 現象の詳細
opCommunityTopicPlugin を無効にすると退会処理でエラー。
( opCommunityTopicPlugin 1.0.2.2 )

再現手順:
1.opCommunityTopicPlugin を無効にする。
2.管理画面から強制退会処理 or ユーザが退会処理を行う

=> 500エラー発生。

発生個所は、

/root/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Relation/Parser.php
メソッド: getRelations()
line: 250

再現しない場合、複合的な要因かもしれません。
とりあえず opCommunityTopicPlugin を有効にしておくことで回避できますが、参考までのご報告です。

Related issues

Related to OpenPNE 3 - Backport(バックポート) #2927: プラグイン無効時にデータ削除を伴う操作でエラーやデータ不整合が発生する Fixed(完了) 2012-03-30
Related to OpenPNE 3 - Backport(バックポート) #3177: プラグイン無効時にデータ削除を伴う操作でエラーやデータ不整合が発生する Fixed(完了) 2012-03-30

Associated revisions

Revision 08f6e9fb (diff)
Added by Rimpei Ogawa almost 7 years ago

(fixes #2911) added pc_backend notice of disabling plugins and new doc plugin installation/uninstallation guide (Japanese only)

History

#1 Updated by Yuma Sakata over 7 years ago

再現確認できました。

Environment (再現バージョン)

OpenPNE 3.6.2
opCommunityTopicPlugin 1.0.3.1

Way to repro (再現手順)

1. 管理画面アプリケーションプラグイン設定ページ(/pc_backend.php/plugin/list)にアクセスする
2. opCommunityTopicPlugin を無効に設定する
3. メンバーリストページ(/pc_backend.php/member)から、任意のメンバーを強制退会する
4. 退会処理でエラーが発生して、強制退会できない

Way to fix (修正内容)

opCommunityTopucPlugin を無効に設定後、退会処理が実行できるように修正お願いします。

#2 Updated by Yuma Sakata over 7 years ago

  • Target version changed from 1.0.x to 1.0.4

#3 Updated by Yuya Watanabe over 7 years ago

  • Status changed from New(新規) to Accepted(着手)
  • Assignee set to Yuya Watanabe

#4 Updated by Yuya Watanabe over 7 years ago

エラー内容

PHP Fatal error:  Class 'opCommunityTopicPluginImagesBehavior' not found in **/lib/model/doctrine/opCommunityTopicPlugin/base/BaseCommunityTopic.class.php on line 94

lib/model/doctrine/opCommunityTopicPlugin/base/BaseCommunityTopic.class.php 94 行目

 92              'foreign' => 'community_topic_id'));
 93 
 94         $opcommunitytopicpluginimagesbehavior0 = new opCommunityTopicPluginImagesBehavior();
 95         $timestampable0 = new Doctrine_Template_Timestampable();
 96         $this->actAs($opcommunitytopicpluginimagesbehavior0);

config/doctrine/schema.yml

  5 CommunityTopic:
  6   actAs:
  7     opCommunityTopicPluginImagesBehavior:
  8     Timestampable:
  9   columns:
 10     id: { type: integer(4), primary: true, autoincrement: true }
 11     community_id: { type: integer(4), notnull: true }
 12     member_id: { type: integer(4) }
 13     name: { type: string, notnull: true }
 14     body: { type: string, notnull: true }
 15     topic_updated_at: { type: timestamp }
 16   relations:
 17     Member:
 18       onDelete: set null
 19     Community:
 20       onDelete: cascade

#5 Updated by Yuya Watanabe over 7 years ago

note-4 の内容を考慮すると,削除する際にロードされるべきクラスがロードされていないことが原因であると思われるため,本体側の問題であると思います.

#6 Updated by Yuma Sakata over 7 years ago

  • Project changed from opCommunityTopicPlugin to OpenPNE 3
  • Target version deleted (1.0.4)

#7 Updated by Yuya Watanabe over 7 years ago

  • Status changed from Accepted(着手) to Pending Fixing(修正待ち)
  • Assignee deleted (Yuya Watanabe)

#8 Updated by Yuya Watanabe over 7 years ago

  • Target version set to OpenPNE 3.8.x

#9 Updated by Yuya Watanabe over 7 years ago

  • Priority changed from Normal(通常) to High(高め)

#10 Updated by Yuya Watanabe over 7 years ago

  • Target version changed from OpenPNE 3.8.x to OpenPNE 3.8.1

#11 Updated by Yuya Watanabe over 7 years ago

  • Assignee set to Kousuke Ebihara

#12 Updated by Yuma Sakata about 7 years ago

  • Target version changed from OpenPNE 3.8.1 to OpenPNE 3.8.x

#13 Updated by Yuma Sakata about 7 years ago

  • Target version changed from OpenPNE 3.8.x to OpenPNE 3.8.2

#14 Updated by Yuma Sakata about 7 years ago

  • Target version changed from OpenPNE 3.8.2 to OpenPNE 3.9.0-old
  • 3.8 で発生するか set to Unknown (未調査)

#15 Updated by Yuma Sakata about 7 years ago

メモ

方針:@ebihara
実装:@nabe

#16 Updated by Mutsumi Imamura almost 7 years ago

  • Assignee changed from Kousuke Ebihara to Rimpei Ogawa

#17 Updated by Rimpei Ogawa almost 7 years ago

  • Subject changed from opCommunityTopicPlugin無効後、退会処理を行うとエラーになる to プラグイン無効時にデータ削除を伴う操作でエラーやデータ不整合が発生する
  • Description updated (diff)
  • Status changed from Pending Fixing(修正待ち) to Accepted(着手)
  • 3.8 で発生するか changed from Unknown (未調査) to Yes (はい)

Description を更新しました。

#18 Updated by Rimpei Ogawa almost 7 years ago

  • Status changed from Accepted(着手) to Pending Review(レビュー待ち)
  • % Done changed from 0 to 50

更新履歴 08f6e9fb192615807bb1e9a8d6d2be404e5f5bcb で適用されました。

#19 Updated by Rimpei Ogawa almost 7 years ago

プラグイン無効時の問題の回避策として「プラグインの削除」を説明する必要があったため、当初管理画面上にプラグインの削除手順を記載する方法を検討しましたが、以下の理由により管理画面上には詳細説明を載せず、インストール・アンインストール手順を説明するための新しいドキュメントを作成する方法を採りました。

  • 管理画面上の既存のプラグインインストール手順の説明には不足があり、プラグインによっては正常にインストールを完了することができない問題があったこと
  • プラグインのインストール・アンインストール手順を正確に書こうとすると、プラグインリストと同一画面で説明するには長くなりすぎること
  • サーバー上のソースコードの管理はおこなわず管理画面のみを利用する管理者にとっては、プラグインのインストール・アンインストールの詳細手順は全く必要ないものであること

#20 Updated by Kousuke Ebihara almost 7 years ago

  • Status changed from Pending Review(レビュー待ち) to Pending Testing(テスト待ち)
  • % Done changed from 50 to 70

#22 Updated by isao sano over 2 years ago

  • Status changed from Pending Testing(テスト待ち) to Won't fix(対応せず)
  • % Done changed from 70 to 0

OpenPNE 3.8.4 にて対応済みであったため、対応せずとします。

Also available in: Atom PDF