package jp.co.bizreach.kinesis import java.util.concurrent.{TimeUnit, Executors} import com.amazonaws.ClientConfiguration import com.amazonaws.auth.AWSCredentialsProvider import com.amazonaws.regions.Regions object BufferedAmazonKinesis { def apply(amount: Int, interval: Long)(implicit region: Regions): BufferedAmazonKinesis = { new BufferedAmazonKinesis(AmazonKinesis(), amount, interval) } def apply(credentials: AWSCredentialsProvider, amount: Int, interval: Long)(implicit region: Regions): BufferedAmazonKinesis = { new BufferedAmazonKinesis(AmazonKinesis(credentials), amount, interval) } def apply(config: ClientConfiguration, amount: Int, interval: Long)(implicit region: Regions): BufferedAmazonKinesis = { new BufferedAmazonKinesis(AmazonKinesis(config), amount, interval) } def apply(credentials: AWSCredentialsProvider, config: ClientConfiguration, amount: Int, interval: Long)(implicit region: Regions): BufferedAmazonKinesis = { new BufferedAmazonKinesis(AmazonKinesis(credentials, config), amount, interval) } def apply(client: AmazonKinesis, amount: Int, interval: Long): BufferedAmazonKinesis = { new BufferedAmazonKinesis(client, amount, interval) } } // TODO Would like to provide DiskBufferClient also class BufferedAmazonKinesis(client: AmazonKinesis, amount: Int, interval: Long) { private val queue = new java.util.concurrent.ConcurrentLinkedQueue[Any] private val scheduler = Executors.newSingleThreadScheduledExecutor() scheduler.scheduleAtFixedRate(new BufferedKinesisSendTask(), 0, interval, TimeUnit.MILLISECONDS) def putRecord(request: PutRecordRequest): Unit = queue.add(request) def putRecords(request: PutRecordsRequest): Unit = queue.add(request) def shutdown(): Unit = { scheduler.shutdownNow() client.shutdown() } /** * Override to handle error in BufferedKinesisSendTask. * This implementation prints stacktrace simply. */ def error(e: Exception): Unit = { e.printStackTrace() } private class BufferedKinesisSendTask extends Runnable { override def run(): Unit = { try { val requests = for(i <- 1 to amount if queue.size() != 0) yield queue.poll() requests.foreach { case r: PutRecordRequest => client.putRecord(r) case r: PutRecordsRequest => client.putRecords(r) } } catch { case e: Exception => error(e) } } } }