From ba207732d9bf1496efabcd1bb1f3741cbe6ef408 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Mon, 24 Aug 2015 10:49:40 +0900 Subject: [PATCH 1/7] 2.5.1-SNAPSHOT begins --- project/Version.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Version.scala b/project/Version.scala index 6d1e91c7..8cf0d08a 100644 --- a/project/Version.scala +++ b/project/Version.scala @@ -1,7 +1,7 @@ object Version { - val octopartsVersion = "2.5" + val octopartsVersion = "2.5.1-SNAPSHOT" val theScalaVersion = "2.11.7" } From c055791bc7d7276b0b56e1ce555d18f4d66734dc Mon Sep 17 00:00:00 2001 From: Lloyd Date: Wed, 7 Oct 2015 14:52:01 +0900 Subject: [PATCH 2/7] Add support for customising ThreadPool queue size - Add the model field + db persistence field w/ tests - Add the field to transformation from the JSON model (update tests) - Add the field to the ThreadPool edit form - Add support for reading the edit and create POST request --- .../octoparts/model/config/ThreadPoolConfig.scala | 5 ++--- .../config/ThreadPoolConfigRepository.scala | 4 +++- app/controllers/AdminController.scala | 4 ++-- app/controllers/AdminForms.scala | 5 +++-- app/views/threadpool/edit.scala.html | 13 ++++++++++++- app/views/threadpool/list.scala.html | 2 ++ .../migration/default/V6__Add_threadpool_queue.sql | 7 +++++++ .../octoparts/model/config/JsonConversionSpec.scala | 13 +++++-------- .../config/HttpPartConfigRepositorySpec.scala | 7 +++++-- test/controllers/AdminControllerSpec.scala | 4 ++-- 10 files changed, 43 insertions(+), 21 deletions(-) create mode 100644 conf/db/migration/default/V6__Add_threadpool_queue.sql diff --git a/app/com/m3/octoparts/model/config/ThreadPoolConfig.scala b/app/com/m3/octoparts/model/config/ThreadPoolConfig.scala index b42514c1..85da4a97 100644 --- a/app/com/m3/octoparts/model/config/ThreadPoolConfig.scala +++ b/app/com/m3/octoparts/model/config/ThreadPoolConfig.scala @@ -13,12 +13,10 @@ case class ThreadPoolConfig( threadPoolKey: String, coreSize: Int = ThreadPoolConfig.defaultCoreSize, hystrixConfigs: Set[HystrixConfig] = Set.empty, + queueSize: Int = ThreadPoolConfig.defaultQueueSize, createdAt: DateTime, updatedAt: DateTime) extends ConfigModel[ThreadPoolConfig] { - // this setting is not yet available for users - def queueSize: Int = ThreadPoolConfig.defaultQueueSize - /** * @return a sorted list of related [[HttpPartConfig]] */ @@ -44,6 +42,7 @@ object ThreadPoolConfig { def fromJsonModel(config: JsonThreadPoolConfig): ThreadPoolConfig = { ThreadPoolConfig( threadPoolKey = config.threadPoolKey, + queueSize = config.queueSize, coreSize = config.coreSize, createdAt = DateTime.now, updatedAt = DateTime.now diff --git a/app/com/m3/octoparts/repository/config/ThreadPoolConfigRepository.scala b/app/com/m3/octoparts/repository/config/ThreadPoolConfigRepository.scala index ceec9383..c84f9f56 100644 --- a/app/com/m3/octoparts/repository/config/ThreadPoolConfigRepository.scala +++ b/app/com/m3/octoparts/repository/config/ThreadPoolConfigRepository.scala @@ -15,7 +15,8 @@ object ThreadPoolConfigRepository extends ConfigMapper[ThreadPoolConfig] with Ti protected val permittedFields = Seq( "threadPoolKey" -> SkinnyParamType.String, - "coreSize" -> SkinnyParamType.Int + "coreSize" -> SkinnyParamType.Int, + "queueSize" -> SkinnyParamType.Int ) lazy val hystrixConfigRef = hasMany[HystrixConfig]( @@ -30,6 +31,7 @@ object ThreadPoolConfigRepository extends ConfigMapper[ThreadPoolConfig] with Ti id = rs.get(n.id), threadPoolKey = rs.get(n.threadPoolKey), coreSize = rs.get(n.coreSize), + queueSize = rs.get(n.queueSize), createdAt = rs.get(n.createdAt), updatedAt = rs.get(n.updatedAt) ) diff --git a/app/controllers/AdminController.scala b/app/controllers/AdminController.scala index b6d34585..cb9f4c53 100644 --- a/app/controllers/AdminController.scala +++ b/app/controllers/AdminController.scala @@ -353,7 +353,7 @@ class AdminController(cacheOps: CacheOps, repository: MutableConfigsRepository)( flashError(routes.AdminController.newThreadPool, Messages("admin.validationErrors", formWithErrors.errors)) } }, { data => - val tpc = ThreadPoolConfig(threadPoolKey = data.threadPoolKey, coreSize = data.coreSize, createdAt = DateTime.now, updatedAt = DateTime.now) + val tpc = ThreadPoolConfig(threadPoolKey = data.threadPoolKey, coreSize = data.coreSize, queueSize = data.queueSize, createdAt = DateTime.now, updatedAt = DateTime.now) saveAndRedirect { repository.save(tpc) }(routes.AdminController.listThreadPools, id => routes.AdminController.showThreadPool(id)) @@ -368,7 +368,7 @@ class AdminController(cacheOps: CacheOps, repository: MutableConfigsRepository)( flashError(routes.AdminController.editThreadPool(id), Messages("admin.validationErrors", formWithErrors.errors)) } }, { data => - val updatedTpc = tpc.copy(threadPoolKey = data.threadPoolKey, coreSize = data.coreSize, updatedAt = DateTime.now) + val updatedTpc = tpc.copy(threadPoolKey = data.threadPoolKey, coreSize = data.coreSize, queueSize = data.queueSize, updatedAt = DateTime.now) saveAndRedirect { repository.save(updatedTpc) }(routes.AdminController.editThreadPool(id), _ => routes.AdminController.showThreadPool(id)) diff --git a/app/controllers/AdminForms.scala b/app/controllers/AdminForms.scala index 96df1f38..80771764 100644 --- a/app/controllers/AdminForms.scala +++ b/app/controllers/AdminForms.scala @@ -229,12 +229,13 @@ object AdminForms { )(ParamData.apply)(ParamData.unapply) ) - case class ThreadPoolData(threadPoolKey: String, coreSize: Int) + case class ThreadPoolData(threadPoolKey: String, coreSize: Int, queueSize: Int) val threadPoolForm = Form( mapping( "threadPoolKey" -> text, - "coreSize" -> number + "coreSize" -> number(min = 1), + "queueSize" -> number(min = 1) )(ThreadPoolData.apply)(ThreadPoolData.unapply) ) diff --git a/app/views/threadpool/edit.scala.html b/app/views/threadpool/edit.scala.html index cf95909b..86de442f 100644 --- a/app/views/threadpool/edit.scala.html +++ b/app/views/threadpool/edit.scala.html @@ -1,4 +1,5 @@ @(maybeTpc: Option[com.m3.octoparts.model.config.ThreadPoolConfig])(implicit flash: Flash, navbarLinks: presentation.NavbarLinks, lang: Lang) +@import com.m3.octoparts.model.config.ThreadPoolConfig @title = @{ maybeTpc match { @@ -44,7 +45,17 @@

@title

- + +
+
+ + + +
+ +
+
+
diff --git a/app/views/threadpool/list.scala.html b/app/views/threadpool/list.scala.html index bd69e571..8fac0862 100644 --- a/app/views/threadpool/list.scala.html +++ b/app/views/threadpool/list.scala.html @@ -22,6 +22,7 @@ @Messages("threadPools.key") @Messages("threadPools.coreSize") + @Messages("threadPools.queueSize") @Messages("threadPools.members") @Messages("action") @@ -31,6 +32,7 @@ @tpc.threadPoolKey @tpc.coreSize + @tpc.queueSize @tpc.hystrixConfigs.size @Messages("edit") diff --git a/conf/db/migration/default/V6__Add_threadpool_queue.sql b/conf/db/migration/default/V6__Add_threadpool_queue.sql new file mode 100644 index 00000000..5ec4918b --- /dev/null +++ b/conf/db/migration/default/V6__Add_threadpool_queue.sql @@ -0,0 +1,7 @@ +ALTER TABLE thread_pool_config +ADD COLUMN queue_size INTEGER + NOT NULL + DEFAULT 256 + CHECK (queue_size > 0); + +COMMENT ON COLUMN thread_pool_config.queue_size IS 'size of the execution queue for a specific thread pool'; \ No newline at end of file diff --git a/test/com/m3/octoparts/model/config/JsonConversionSpec.scala b/test/com/m3/octoparts/model/config/JsonConversionSpec.scala index b3ba1656..046c4f5b 100644 --- a/test/com/m3/octoparts/model/config/JsonConversionSpec.scala +++ b/test/com/m3/octoparts/model/config/JsonConversionSpec.scala @@ -149,9 +149,8 @@ class JsonConversionSpec extends FunSpec with Matchers with Checkers with Genera val tpc = ThreadPoolConfig.fromJsonModel(jtpc) tpc.threadPoolKey should be(jtpc.threadPoolKey) tpc.coreSize should be(jtpc.coreSize) - // This queueSize setting is not open yet - tpc.queueSize should be(ThreadPoolConfig.defaultQueueSize) - ThreadPoolConfig.toJsonModel(tpc) should be(jtpc.copy(queueSize = ThreadPoolConfig.defaultQueueSize)) + tpc.queueSize should be(jtpc.queueSize) + ThreadPoolConfig.toJsonModel(tpc) shouldBe jtpc } } @@ -160,11 +159,9 @@ class JsonConversionSpec extends FunSpec with Matchers with Checkers with Genera jhc: json.HystrixConfig => val hc = HystrixConfig.fromJsonModel(jhc) hc.timeout should be(jhc.timeout) - val ejtpc = jhc.threadPoolConfig.copy(queueSize = ThreadPoolConfig.defaultQueueSize) - hc.threadPoolConfig.map(ThreadPoolConfig.toJsonModel) should be(Some(ejtpc)) hc.commandKey should be(jhc.commandKey) hc.commandGroupKey should be(jhc.commandGroupKey) - HystrixConfig.toJsonModel(hc) should be(jhc.copy(threadPoolConfig = ejtpc)) + HystrixConfig.toJsonModel(hc) shouldBe jhc } } @@ -202,7 +199,7 @@ class JsonConversionSpec extends FunSpec with Matchers with Checkers with Genera hpc.uriToInterpolate should be(jhpc.uriToInterpolate) hpc.description should be(jhpc.description) hpc.method should be(jhpc.method) - val ejhc = jhpc.hystrixConfig.copy(threadPoolConfig = jhpc.hystrixConfig.threadPoolConfig.copy(queueSize = ThreadPoolConfig.defaultQueueSize)) + val ejhc = jhpc.hystrixConfig hpc.hystrixConfig.map(HystrixConfig.toJsonModel) should be(Some(ejhc)) hpc.additionalValidStatuses should equal(jhpc.additionalValidStatuses.to[SortedSet]) hpc.parameters.map(PartParam.toJsonModel) should be(jhpc.parameters.to[SortedSet]) @@ -214,7 +211,7 @@ class JsonConversionSpec extends FunSpec with Matchers with Checkers with Genera hpc.alertPercentThreshold should be(jhpc.alertMailSettings.alertPercentThreshold) hpc.alertInterval should be(jhpc.alertMailSettings.alertInterval) hpc.alertMailRecipients should be(jhpc.alertMailSettings.alertMailRecipients) - HttpPartConfig.toJsonModel(hpc) should be(jhpc.copy(hystrixConfig = ejhc)) + HttpPartConfig.toJsonModel(hpc) shouldBe jhpc } } } diff --git a/test/com/m3/octoparts/repository/config/HttpPartConfigRepositorySpec.scala b/test/com/m3/octoparts/repository/config/HttpPartConfigRepositorySpec.scala index 45dfaaff..4b881316 100644 --- a/test/com/m3/octoparts/repository/config/HttpPartConfigRepositorySpec.scala +++ b/test/com/m3/octoparts/repository/config/HttpPartConfigRepositorySpec.scala @@ -159,7 +159,8 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat ) val threadPoolConfigId = ThreadPoolConfigRepository.createWithAttributes( 'threadPoolKey -> "swimmingpool", - 'coreSize -> 10 + 'coreSize -> 10, + 'queueSize -> 500 ) HystrixConfigRepository.createWithAttributes( 'httpPartConfigId -> partId, @@ -189,6 +190,7 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat val Some(threadPoolConfig) = hystrixConfig.threadPoolConfig // will fail if not eager loaded threadPoolConfig.threadPoolKey should be("swimmingpool") threadPoolConfig.coreSize should be(10) + threadPoolConfig.queueSize should be(500) } } @@ -200,7 +202,7 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat PartParam(required = false, versioned = false, paramType = ParamType.Header, outputName = "myHeader", createdAt = DateTime.now, updatedAt = DateTime.now) ) - lazy val threadPool = ThreadPoolConfig(threadPoolKey = "myThreadPool", coreSize = 5, createdAt = DateTime.now, updatedAt = DateTime.now) + lazy val threadPool = ThreadPoolConfig(threadPoolKey = "myThreadPool", coreSize = 5, queueSize = 500, createdAt = DateTime.now, updatedAt = DateTime.now) /* Inside a method that takes a session because we need to refer to a valid ThreadPoolConfig id when @@ -252,6 +254,7 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat observedThreadPoolConfig.threadPoolKey should be(threadPool.threadPoolKey) observedThreadPoolConfig.coreSize should be(threadPool.coreSize) + observedThreadPoolConfig.queueSize should be(threadPool.queueSize) } describe("to insert") { diff --git a/test/controllers/AdminControllerSpec.scala b/test/controllers/AdminControllerSpec.scala index 0625b0f8..981463bb 100644 --- a/test/controllers/AdminControllerSpec.scala +++ b/test/controllers/AdminControllerSpec.scala @@ -531,7 +531,7 @@ class AdminControllerSpec extends FunSpec val adminController = new AdminController(cacheOps = DummyCacheOps, repository = repository) doReturn(Future.successful(76L)).when(repository).save(anyObject[ThreadPoolConfig]())(anyObject[ConfigMapper[ThreadPoolConfig]], anyObject[Span]) val createThreadPool = adminController.createThreadPool( - FakeRequest().withFormUrlEncodedBody("threadPoolKey" -> "myNewThreadPool", "coreSize" -> "99") + FakeRequest().withFormUrlEncodedBody("threadPoolKey" -> "myNewThreadPool", "coreSize" -> "99", "queueSize" -> "987") ) whenReady(createThreadPool) { result => status(createThreadPool) should be(FOUND) @@ -549,7 +549,7 @@ class AdminControllerSpec extends FunSpec doReturn(Future.successful(Some(tpc))).when(repository).findThreadPoolConfigById(anyLong())(anyObject[Span]) doReturn(Future.successful(123L)).when(repository).save(anyObject[ThreadPoolConfig]())(anyObject[ConfigMapper[ThreadPoolConfig]], anyObject[Span]) - val updateThreadPool = adminController.updateThreadPool(123L)(FakeRequest().withFormUrlEncodedBody("threadPoolKey" -> "myNewThreadPool", "coreSize" -> "99")) + val updateThreadPool = adminController.updateThreadPool(123L)(FakeRequest().withFormUrlEncodedBody("threadPoolKey" -> "myNewThreadPool", "queueSize" -> "512", "coreSize" -> "99")) whenReady(updateThreadPool) { result => verify(repository).findThreadPoolConfigById(123L) From 55427ea4df32f71521c8e37d3369ada8487af305 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Wed, 7 Oct 2015 14:56:02 +0900 Subject: [PATCH 3/7] Min queue size is 0 for no queue --- app/controllers/AdminForms.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/AdminForms.scala b/app/controllers/AdminForms.scala index 80771764..0e9269d2 100644 --- a/app/controllers/AdminForms.scala +++ b/app/controllers/AdminForms.scala @@ -235,7 +235,7 @@ object AdminForms { mapping( "threadPoolKey" -> text, "coreSize" -> number(min = 1), - "queueSize" -> number(min = 1) + "queueSize" -> number(min = 0) )(ThreadPoolData.apply)(ThreadPoolData.unapply) ) From 20ef939753145887878a126ee48410bb638cbb17 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Wed, 7 Oct 2015 15:49:50 +0900 Subject: [PATCH 4/7] Add a selenium test for the add threadpool page --- test/integration/AdminSpec.scala | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 test/integration/AdminSpec.scala diff --git a/test/integration/AdminSpec.scala b/test/integration/AdminSpec.scala new file mode 100644 index 00000000..3227704d --- /dev/null +++ b/test/integration/AdminSpec.scala @@ -0,0 +1,50 @@ +package integration + +import org.openqa.selenium.htmlunit.HtmlUnitDriver +import org.scalatest.{ Matchers, FunSpec } +import org.scalatest.selenium.{ Page => SeleniumPage } +import org.scalatest.concurrent.{ IntegrationPatience, ScalaFutures } +import org.scalatestplus.play.{ HtmlUnitFactory, OneBrowserPerSuite, OneServerPerSuite } + +class AdminSpec + extends FunSpec + with OneServerPerSuite + with OneBrowserPerSuite + with HtmlUnitFactory + with Matchers + with ScalaFutures + with IntegrationPatience { + + val htmlunitDriver = webDriver.asInstanceOf[HtmlUnitDriver] + htmlunitDriver.setJavascriptEnabled(false) + + def baseUrl: String = { + s"http://localhost:$port" + } + + object ThreadPoolAddPage extends SeleniumPage { + val url: String = s"$baseUrl/admin/thread-pools/new" + } + + describe("adding a thread pool") { + + it("should work and redirect me to the show page") { + val name = s"my little pool ${java.util.UUID.randomUUID}" + val size = 10 + val queueSize = 500 + goTo(ThreadPoolAddPage) + textField("threadPoolKey").value = name + numberField("coreSize").value = s"$size" + numberField("queueSize").value = s"$queueSize" + submit() + eventually { + pageTitle should include("Thread pool details") + } + val descriptors = findAll(TagNameQuery("dd")) + descriptors.find(_.text == name) shouldBe 'defined + descriptors.find(_.text == size.toString) shouldBe 'defined + descriptors.find(_.text == queueSize.toString) shouldBe 'defined + } + + } +} From c7b0c27a46f52db443244efc00ab1f906d3c07d6 Mon Sep 17 00:00:00 2001 From: Lloyd Date: Mon, 19 Oct 2015 11:56:54 +0900 Subject: [PATCH 5/7] Fix QueueSize setting 1. withQueueSizeRejectionThreshold needs to be set (this is what actually controls the max queue size, effectively) 2. Retrictions should be min of -1 in order to disable the queue (See Hystrix implementation) 3. Add hint on what QueueSize settings do and how to disable the queue 4. Make Zipkin provisioning idempotent for great good --- .../hystrix/HystrixSetterSupport.scala | 9 +++++--- app/controllers/AdminForms.scala | 2 +- app/views/threadpool/edit.scala.html | 3 ++- .../default/V6__Add_threadpool_queue.sql | 2 +- conf/messages.en | 1 + conf/messages.ja | 1 + .../config/HttpPartConfigRepositorySpec.scala | 21 +++++++++++++++---- .../provisioning/roles/zipkin/tasks/main.yml | 2 ++ 8 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/com/m3/octoparts/hystrix/HystrixSetterSupport.scala b/app/com/m3/octoparts/hystrix/HystrixSetterSupport.scala index b99d5929..e4b00d38 100644 --- a/app/com/m3/octoparts/hystrix/HystrixSetterSupport.scala +++ b/app/com/m3/octoparts/hystrix/HystrixSetterSupport.scala @@ -13,13 +13,16 @@ trait HystrixSetterSupport { * Given a HystrixArgument case class returns a HystrixCommand.Setter object */ def setter(config: HystrixConfig): HystrixCommand.Setter = { + val threadPoolConfig = config.threadPoolConfigItem val threadPoolProperties = HystrixThreadPoolProperties.Setter(). - withCoreSize(config.threadPoolConfigItem.coreSize). - withMaxQueueSize(config.threadPoolConfigItem.queueSize) + withCoreSize(threadPoolConfig.coreSize). + // Hystrix uses both of these for setting Queue size + withMaxQueueSize(threadPoolConfig.queueSize). + withQueueSizeRejectionThreshold(threadPoolConfig.queueSize) HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(config.commandGroupKey)). andCommandKey(HystrixCommandKey.Factory.asKey(config.commandKey)). - andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(config.threadPoolConfigItem.threadPoolKey)). + andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey(threadPoolConfig.threadPoolKey)). andThreadPoolPropertiesDefaults(threadPoolProperties). andCommandPropertiesDefaults(HystrixCommandProperties.Setter(). withExecutionTimeoutInMilliseconds(config.timeout.toMillis.toInt). diff --git a/app/controllers/AdminForms.scala b/app/controllers/AdminForms.scala index 0e9269d2..d74b6279 100644 --- a/app/controllers/AdminForms.scala +++ b/app/controllers/AdminForms.scala @@ -235,7 +235,7 @@ object AdminForms { mapping( "threadPoolKey" -> text, "coreSize" -> number(min = 1), - "queueSize" -> number(min = 0) + "queueSize" -> number(min = -1) // Hystrix says that if -1 is used, it will use a synchronous queue )(ThreadPoolData.apply)(ThreadPoolData.unapply) ) diff --git a/app/views/threadpool/edit.scala.html b/app/views/threadpool/edit.scala.html index 86de442f..58282746 100644 --- a/app/views/threadpool/edit.scala.html +++ b/app/views/threadpool/edit.scala.html @@ -55,7 +55,8 @@

@title

- + +

@Messages("threadPools.queueSizeExplanation")

diff --git a/conf/db/migration/default/V6__Add_threadpool_queue.sql b/conf/db/migration/default/V6__Add_threadpool_queue.sql index 5ec4918b..3fcc551a 100644 --- a/conf/db/migration/default/V6__Add_threadpool_queue.sql +++ b/conf/db/migration/default/V6__Add_threadpool_queue.sql @@ -2,6 +2,6 @@ ALTER TABLE thread_pool_config ADD COLUMN queue_size INTEGER NOT NULL DEFAULT 256 - CHECK (queue_size > 0); + CHECK (queue_size >= -1); COMMENT ON COLUMN thread_pool_config.queue_size IS 'size of the execution queue for a specific thread pool'; \ No newline at end of file diff --git a/conf/messages.en b/conf/messages.en index 9471b94e..9223afe8 100644 --- a/conf/messages.en +++ b/conf/messages.en @@ -114,6 +114,7 @@ threadPools.edit=Edit settings for thread pool {0} threadPools.key=Thread pool key threadPools.coreSize=Core size threadPools.queueSize=Queue size +threadPools.queueSizeExplanation=-1 → no queue threadPools.members=Members cacheGroups.this=Cache group diff --git a/conf/messages.ja b/conf/messages.ja index 969b9409..103f7040 100644 --- a/conf/messages.ja +++ b/conf/messages.ja @@ -113,6 +113,7 @@ threadPools.edit=「{0}」スレッドプール設定編集 threadPools.key=スレッドプールキー threadPools.coreSize=コア数 threadPools.queueSize=キュー数 +threadPools.queueSizeExplanation=-1 → キューなし threadPools.members=メンバーパーツ cacheGroups.this=キャッシュグループ diff --git a/test/com/m3/octoparts/repository/config/HttpPartConfigRepositorySpec.scala b/test/com/m3/octoparts/repository/config/HttpPartConfigRepositorySpec.scala index 4b881316..497e6f2c 100644 --- a/test/com/m3/octoparts/repository/config/HttpPartConfigRepositorySpec.scala +++ b/test/com/m3/octoparts/repository/config/HttpPartConfigRepositorySpec.scala @@ -1,6 +1,7 @@ package com.m3.octoparts.repository.config import java.nio.charset.StandardCharsets +import java.sql.SQLException import com.m3.octoparts.model.HttpMethod._ import com.m3.octoparts.model.config._ @@ -149,7 +150,7 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat describe("hasOne HystrixConfig") { - def setup(implicit session: DBSession): Long = { + def setup(queueSize: Int = 500)(implicit session: DBSession): Long = { val partId = HttpPartConfigRepository.createWithAttributes(httpPartConfigMapWithDeprecation: _*) PartParamRepository.createWithAttributes( 'httpPartConfigId -> partId, @@ -160,7 +161,7 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat val threadPoolConfigId = ThreadPoolConfigRepository.createWithAttributes( 'threadPoolKey -> "swimmingpool", 'coreSize -> 10, - 'queueSize -> 500 + 'queueSize -> queueSize ) HystrixConfigRepository.createWithAttributes( 'httpPartConfigId -> partId, @@ -174,7 +175,7 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat it("should be possible to retrieve the HystrixConfig of a HttpPartConfig with the .joins method") { implicit session => - val partId = setup(session) + val partId = setup() val config = HttpPartConfigRepository.joins(HttpPartConfigRepository.hystrixConfigRef).findById(partId).get val hystrixConfig = config.hystrixConfig.get hystrixConfig.timeout should be(3.seconds) @@ -184,7 +185,7 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat it("should be possible to retrieve the HystrixConfig of a HttpPartConfig, along with it's ThreadPoolConfig, using the .includes method") { implicit session => - val partId = setup(session) + val partId = setup() val config = HttpPartConfigRepository.includes(HttpPartConfigRepository.hystrixConfigRef).findById(partId).get val hystrixConfig = config.hystrixConfig.get val Some(threadPoolConfig) = hystrixConfig.threadPoolConfig // will fail if not eager loaded @@ -193,6 +194,18 @@ class HttpPartConfigRepositorySpec extends fixture.FunSpec with DBSuite with Mat threadPoolConfig.queueSize should be(500) } + it("should allow us to save with queueSize of -1") { + implicit session => + setup(-1) + } + + it("should not allow us to save if queueSize is less than -1") { + implicit session => + intercept[SQLException] { + setup(-2) + } + } + } describe(".save") { diff --git a/vaygrant/provisioning/roles/zipkin/tasks/main.yml b/vaygrant/provisioning/roles/zipkin/tasks/main.yml index dc56aba0..319fc9e2 100644 --- a/vaygrant/provisioning/roles/zipkin/tasks/main.yml +++ b/vaygrant/provisioning/roles/zipkin/tasks/main.yml @@ -54,6 +54,7 @@ - name: Extract Zipkin Source (Zipkin Web only) command: unzip /tmp/zipkin-1.1.0-src.zip "zipkin-1.1.0/zipkin-web/*" -d /opt/zipkin + creates=/opt/zipkin sudo: yes sudo_user: zipkin tags: zipkin @@ -61,6 +62,7 @@ - name: Move Zipkin Web Source folder command: mv /opt/zipkin/zipkin-1.1.0/zipkin-web /opt/zipkin/zipkin-web + creates=/opt/zipkin/zipkin-web sudo: yes sudo_user: zipkin tags: zipkin From f93602c6592e4b3b71c89cc122ab0ddbc4cf5dcf Mon Sep 17 00:00:00 2001 From: Lloyd Date: Mon, 19 Oct 2015 12:22:27 +0900 Subject: [PATCH 6/7] Make thread pool setter configuration transform testable and test it --- .../hystrix/HystrixSetterSupport.scala | 19 +++++++++++------- .../hystrix/HystrixSetterSupportSpec.scala | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) create mode 100644 test/com/m3/octoparts/hystrix/HystrixSetterSupportSpec.scala diff --git a/app/com/m3/octoparts/hystrix/HystrixSetterSupport.scala b/app/com/m3/octoparts/hystrix/HystrixSetterSupport.scala index e4b00d38..4a8fa106 100644 --- a/app/com/m3/octoparts/hystrix/HystrixSetterSupport.scala +++ b/app/com/m3/octoparts/hystrix/HystrixSetterSupport.scala @@ -1,6 +1,7 @@ package com.m3.octoparts.hystrix -import com.m3.octoparts.model.config.HystrixConfig +import com.m3.octoparts.model.config.{ ThreadPoolConfig, HystrixConfig } +import com.netflix.hystrix.HystrixThreadPoolProperties.Setter import com.netflix.hystrix._ /** @@ -13,12 +14,8 @@ trait HystrixSetterSupport { * Given a HystrixArgument case class returns a HystrixCommand.Setter object */ def setter(config: HystrixConfig): HystrixCommand.Setter = { - val threadPoolConfig = config.threadPoolConfigItem - val threadPoolProperties = HystrixThreadPoolProperties.Setter(). - withCoreSize(threadPoolConfig.coreSize). - // Hystrix uses both of these for setting Queue size - withMaxQueueSize(threadPoolConfig.queueSize). - withQueueSizeRejectionThreshold(threadPoolConfig.queueSize) + val threadPoolConfig: ThreadPoolConfig = config.threadPoolConfigItem + val threadPoolProperties = threadPoolSetter(threadPoolConfig) HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(config.commandGroupKey)). andCommandKey(HystrixCommandKey.Factory.asKey(config.commandKey)). @@ -28,4 +25,12 @@ trait HystrixSetterSupport { withExecutionTimeoutInMilliseconds(config.timeout.toMillis.toInt). withFallbackEnabled(config.localContentsAsFallback)) } + + private[hystrix] def threadPoolSetter(threadPoolConfig: ThreadPoolConfig): Setter = { + HystrixThreadPoolProperties.Setter(). + withCoreSize(threadPoolConfig.coreSize). + // Hystrix uses both of these for setting Queue size + withMaxQueueSize(threadPoolConfig.queueSize). + withQueueSizeRejectionThreshold(threadPoolConfig.queueSize) + } } diff --git a/test/com/m3/octoparts/hystrix/HystrixSetterSupportSpec.scala b/test/com/m3/octoparts/hystrix/HystrixSetterSupportSpec.scala new file mode 100644 index 00000000..03ca4639 --- /dev/null +++ b/test/com/m3/octoparts/hystrix/HystrixSetterSupportSpec.scala @@ -0,0 +1,20 @@ +package com.m3.octoparts.hystrix + +import com.m3.octoparts.support.mocks.ConfigDataMocks +import org.scalatest._ + +class HystrixSetterSupportSpec extends FunSpec with Matchers with ConfigDataMocks { + + val subject = new HystrixSetterSupport {} + + describe("#threadPoolSetter") { + + it("should return a Hystrix ThreadPool setter with queue size and queue threshold size set to the config item's queue size") { + val r = subject.threadPoolSetter(mockThreadConfig) + r.getMaxQueueSize shouldBe mockThreadConfig.queueSize + r.getQueueSizeRejectionThreshold shouldBe mockThreadConfig.queueSize + } + + } + +} From 5f087a74e40db327e21fa1cb9ef14590e2d8834a Mon Sep 17 00:00:00 2001 From: Lloyd Date: Mon, 26 Oct 2015 09:57:28 +0900 Subject: [PATCH 7/7] Bump version --- project/Version.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/Version.scala b/project/Version.scala index 8cf0d08a..67875d5d 100644 --- a/project/Version.scala +++ b/project/Version.scala @@ -1,7 +1,7 @@ object Version { - val octopartsVersion = "2.5.1-SNAPSHOT" + val octopartsVersion = "2.5.1" val theScalaVersion = "2.11.7" }