elasticsearch의 connection pool을 만들고 slick이나 play2처럼 자원 객체를 열고 닫는 불편함을 줄이고 싶었다.


보통 java/spring을 사용한 경우라면 val connection = connectionPool.getObject() 한 후,

코드 작업 후에 connectionPool.returnObjejct()를 호출해서 자원을 반환하는 구조를 사용하는 것이 일반적인 패턴이다. (사실 이게 귀찮으면 interceptor(asepectJ)를 사용하기도 한다)




다음은 es pool 예제이다. apache pool과 elastic4s(https://github.com/sksamuel/elastic4s)를 사용했다. 

object ElasticsearchPoolManager {
val poolConfig: ElasticsearchPoolConfig = new ElasticsearchPoolConfig()
lazy val pool: ElasticsearchPool = new ElasticsearchPool(poolConfig, "googles")

def getObject(): ElasticsearchConnectionSource = {
pool.getResource()
}

def returnObject(esSource: ElasticsearchConnectionSource) = {
pool.returnResource(esSource)
}

def withES[A](block: ElasticsearchConnectionSource => A): A = {
val source = getObject()
try { block(source) }
finally { returnObject(source)}
}
}



withES를 사용함으로서 코드 블록을 감싸게 했고.. 자동으로 getObject와 returnObject 코드를 사용하지 않도록 했다.


@Singleton
class ElasticsearchDAO {
val SIZE = 10
val INDEX_DEFULT_TYPE = "fluentd"
import com.sksamuel.elastic4s.http.ElasticDsl._

def getData(searchData: SearchData): Unit = {
import elasticsearch.pool.KemiElasticsearchPoolManager._
withES { es =>
val client = es.client
val result = client.execute {
search(searchData.serviceTag / INDEX_DEFULT_TYPE).query {
rangeQuery("@timestamp") .gte(searchData.startDateTime).lte(searchData.endDateTime)
}.size(SIZE).sortByFieldDesc("@timestamp")
}.await

result.hits.hits.foreach { println }
}
}
}



아.. 이전보다는 깔끔하다..






Posted by '김용환'
,