2017-09-05 140 views
1

重い計算を実行し、大きな結果(ファイルにダウンロードされる)を生成するRESTサービス(RESTeasyを使用)を開発しています。 システムを保護するために、同時呼び出しを防止して同じユーザーによる実行を制限することにしました。RESTサービス:ユーザーあたりの同時呼び出しを防止する

私はこのように、セッションに変数を置くことを考えた:ユーザーごと、ない

//check if service is running before execution if (Boolean.parseBoolean((String) session.getAttribute("isRunning"))) { throw new WebApplicationException(Response.status( Response.Status.FORBIDDEN).entity("Service is currently running!").build()); } //on execution session.setAttribute("isRunning", "true"); //after execution finally { session.setAttribute("isRunning", "false"); } 

が、これは、セッション
あたりの使用量 を制限します。

+0

どのようにあなたのシステムは、ユーザを識別していますか?ログオン操作を受け入れてセッションを作成するか、各要求と共に送信される資格情報ですか、クライアント証明書などを使用していますか? –

+0

はい。私は、要求オブジェクトを通じてユーザーにアクセスします。認証はBASICスキームで行われます – MoneerOmar

答えて

1

あなたは正しい方向にあります。

セッションにセットを格納します(これをUserSetと呼びます)。あなたが要求を取得すると

、 は、次の操作を行います。

  1. は、ユーザを識別します。
  2. アプリケーションスコープからUserSetを取得します。
  3. UserSetで同期します。
  4. ユーザーが既にUserSetに存在するかどうかを確認します。
  5. はいの場合は、要求を短絡してWebサービスコールを終了します。
  6. いいえの場合は、UserSetにユーザーを追加します。
  7. 同期ブロックを終了します。
  8. 長時間実行する操作を実行します。
  9. UserSetで同期します。
  10. セットからユーザーを削除します。

編集:John Wuコメントに基づいて修正された範囲。

+0

"UserSet"はセッション状態ではなくアプリケーション状態で保存する必要があると考えます。それ以外の場合、常に現在のユーザーは1人だけです。 –

0

@dwbによって提案されたアプローチの構築、ここに私の答えは次のとおりです。

//globally defined set holding ids of users currently executing the service 
private static Set<String> currentUsers = Collections.synchronizedSortedSet(new TreeSet<String>()); 


//check if service is running before execution 
if (isCurrentlyRunningByUser(request.getRemoteUser())) { 
     throw new WebApplicationException(Response.status(Response.Status.FORBIDDEN).entity("Service is currently running!").build()); 
} 


//after execution 
finally { 
    currentUsers.remove(user); 
} 



/** 
* checks if user is currently running the service. if yes, returns true. 
* if no, add user to current users set, and returns false 
* @param remoteUser user asking to execute the service 
* @return true if service is being run by the user 
*/ 
private boolean isCurrentlyRunningByUser(String user) { 
    synchronized (currentUsers) { 
     Iterator it = currentUsers.iterator(); 
     while (it.hasNext()) { 
      if (user.equals(it.next())) { 
       return true; 
      } 
     } 
     currentUsers.add(user); 
    } 
    return false; 
} 
関連する問題