arcanum_jp’s blog

おっさんの日記

Twitter botが作りたい。(収集スレッド)

TwitterBOTを作る際によく考えるのが、Twitterから特定ワードなどを検索して溜め込むような「定時に起動して処理する」ようなバッチ処理。Threadを使って作っていたけど同じような処理ばっかなので切り出してみた。いわゆるフレーム化。必要な機能としては以下のような機能があればよいのかな?

  • 指定した間隔で起動する
  • シングルトンパターンのインスタンス
  • 起動中のインスタンスを取得でき、いつでも終了できる機能
  • 現在起動中かどうかを教えてくれる機能
  • コネクションの取得もやってくれる


以下のソースはまだスレッドセーフなんて考えていない。(スレッドセーフってなに?)またThreadクラスである必要も無いと思う。使う人は考えて使ってください。

public abstract class AbstractBatchManager extends Thread{

  protected boolean _managerStop;
  public void managerStop(){
    _managerStop = true;
  }

  private int _intervalsecond;
  public void setIntervalSecond(int intervalsecond){
    _intervalsecond = intervalsecond;
  }

  private static AbstractBatchManager _instance;

  public static boolean isService(){
    if(_instance == null){
      return false;
    }
    if(!_instance.isAlive()){
      return false;
    }
    return true;
  }

  private static AbstractBatchManager getNewInstance(Class clazz, int intervalsecond){

    AbstractBatchManager ret = null;

    try {
      ret = (AbstractBatchManager)clazz.newInstance();

    } catch (Exception e) {
      throw new RuntimeException(e);
    }
    ret.setIntervalSecond(intervalsecond);
    return ret;

  }

  public static final AbstractBatchManager getInstance(Class clazz, int intervalsecond){

    if(_instance == null){
      _instance = getNewInstance(clazz, intervalsecond);
    }
    if(!isService()){
      _instance = getNewInstance(clazz, intervalsecond);
    }

    return _instance;

  }

  protected abstract void execute(Connection con);

  public void run(){
    try{
      while(!_managerStop){

        Connection con = null;
        try{
          con = ... コネクションを取得する処理
          execute(con);  // サブクラスに処理を任せる
          con.commit();
        }
        catch(Exception e){
          //握りつぶし
        }
        finally{
          if(con!=null)con.close();
        }

        // 指定された秒数待ち合わせ
        for(int i=0; i<_intervalsecond; i++){
          sleep(1000);
          if(_managerStop){
            break;
          }
        }
      }

    }
    catch(Exception e){
      // 握りつぶし
    }

  }

}

使い方は、AbstractBatchManagerを継承したクラスを作ってvoid execute(Connection)を実装しておく、中でTwitter検索をするだのツイートの分析をするだの・・・をする。

public class SearchBach extends AbstractBatchManager{

  protected void execute(Connection){

    ... バッチ処理の実装
  }
}

使うときは、AbstractBatchManagerに用意しておいたメソッドで取得して実行する。

...

// 3600秒眠って起動
AbstractBatchManage batch = 
          AbstractBatchManage.getInstance(SearchBach.class, 3600)

batch.start();


終了するときはmanagerStop()で終了。

AbstractBatchManage batch = 
          AbstractBatchManage.getInstance(SearchBach.class, 3600)

batch.managerStop();