質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.23%

複数実行されても処理は1つだけに制限する方法

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,125

msx2

score 164

FTPサーバーにファイルを送信する処理の実装で悩んでいます。
PHPを使って処理しています。

やりたいことは画面からのリクエストでデータベースを更新するcsvファイルを作成し、FTPサーバーにアップロードするだけですが以下の制約があります。

・アップロードするファイル名は固定(main.csvとoption.csvの2種類)
・ファイルは1つずつ送信する必要がある
・1つのファイルが処理されるのに1分~10分程度かかる場合がある(サーバーの状態による)

複数のリクエストが同時に発生することがありますが、この制約により順番に1件ずつ処理しないといけません。

処理のイメージとしては画面からのリクエストで処理をデータベースに登録して、別にアップロードを行う処理をcronで定期的に起動し、順番に実行していくのかと思います。

ただしアップロード処理に時間がかかる場合があるため前の処理が実行中に次の定期実行が行われてしまうことが考えられます。
アップロードを行う処理は1つだけしか実行して欲しくないのをどうやって実現すればいいか悩んでいます。

実行前にデータベースに処理中フラグを立て、処理が終了したらフラグを消す方法しか思いつかないのですが、他にいい方法はないでしょうか?

PHPで特定の処理が実行中かどうかを知る方法というのはあるでしょうか?

よろしくお願い致します。

追記

二重起動対応にご回答いただいたpsコマンドやロックファイルが使われるみたいですね。

こちらのQiita記事にもまとめてありました。
http://qiita.com/n0bisuke/items/ad7c37d68ff0d5b87742

言葉を知らないとこういう記事を見つけられないので本当に助かります。。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+1

phpでftpのアップロードをやる意味があるのでしょうか?
とくに10分も待たされる可能性があるならタイムアウトしそうですし
向いているとは思いません。
なんらかのコマンドライン系のftpクライアントで処理するのが
賢明だとおもいます。

ファイルは1つずつ送信する必要がある

の仕様についてはFTPの仕組み上あまり意味がないと思いますが
コマンドライン系の処理なら順番にputを指定してやれば
並行処理にはならないと思います

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/01 13:12

    送信するファイル名が固定されているので複数送信するとcsvファイルが上書きされてしまうのです。
    csvファイルでしか連携できない謎のシステムで送信先の仕様なので従うしかない状況なんです。。

    ちなみに送信したcsvファイルは相手のサーバー上で処理されると自動的に削除されるので、ファイルが消えるのを待って次のファイルを送ります。

    キャンセル

+1

処理開始時に処理中を示すファイル(固定ファイル名)を生成して、
処理終了時に削除する、のはいかがでしょうか。

一度に複数のアクセスが有るな話ではなさそうだし、
完全に自分の管理下で行う処理のようなので、
そんなので十分かと思いました。

固定ファイル名に、
例えば処理開始日時をファイルに出力しておくと、
そのファイルを参照するphp処理で
経過時間もわかるわけです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/01 13:15

    なるほど!アイデア的にはデータベースに状態を持たせるのと似ていますがファイルを使う方が安全ですね。
    あまりに時間が経過し過ぎていたら破棄することもできますし。
    いつもありがとうございます。

    キャンセル

checkベストアンサー

0

仕様に不明な点もありますが、勝手な考えで書いてみます。

前提
・画面からのリクエストデータにデータベースを更新する「何か」が入っている。

●画面からのリクエスト処理
1.リクエストがあったら、リクエストの中の「何か」をファイルに書き出す。
ファイル名は一意にするために、例えば「yyyymmddHHMMSS_[セッションID].txt」にする
※リクエストがあるたびにファイルは増えていきます。

●FTP処理
cronにより定期的に実行される
1.起動時にpsコマンドで自分(自分と同じ名前の処理がいるか)を確認する。
※cronから起動するプログラム名がftp.shであればpsコマンドでftp.shが存在することを確認する。
いれば、処理中と解釈し処理は終了する。
いない場合は、処理を継続する(2へ)
2.相手サーバ上にmain.csv,option.csvが存在しないことを確認
存在する場合は終了
存在しない場合は処理を継続する(3へ)
3.リクエストがあった際に作成された複数のファイルを古い順に読み込み、
「何か」をmain.csvやoption.csvに書き出す。
4.ftpでmain.csvとoption.csvを送信
5.ftp送信に成功したらリクエストファイルを削除する。
※3で読み込んだファイルのみが対象
6.終了

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/01 17:08

    psコマンド!!こんなコマンドがあったんですね。
    まさにやりたい内容です!

    全てのファイルを送信してしまいたいので
    ・2番のサーバー上にファイルが存在する場合は終了せずに再確認を繰り返して3に進む
    ・5番が完了したら2番に戻る(送信対象がなくなるまで)

    これで何とか問題を解決できると思います。
    ご回答ありがとうございました!

    キャンセル

0

めんどくさいだけで、難しさはないと思いますが、

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/08/01 14:13

    確かに難しく考えすぎだったかも知れませんね
    アップロードを行う処理を落ちないように丁寧に作れば大丈夫そうでした。
    ありがとうございます。

    キャンセル

  • 2017/08/01 17:22 編集

    すいません。この回答、別の質問への回答だったのですが、何故か間違えて投稿してしまいました。
    本来するつもりだった回答は、下記です。

    待ち行列が途切れないようなケースではなく、たまに実行が重なるかも、という程度であるなら、排他制御をして、ロックが取れるまで時間待ちをすればいいと思います。

    キャンセル

  • 2017/08/01 17:24

    大丈夫ですw
    またよろしくお願いします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.23%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる