{"action":"created","comment":{"url":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/comments/48088341","id":48088341,"diff_hunk":"@@ -3,138 +3,98 @@\n //\n package com.ironcorelabs.davenport\n \n-import scalaz.\\/, scalaz.concurrent.Task\n+import scalaz._, scalaz.concurrent.Task\n+import scalaz.syntax.monad._ // Brought in for .join\n \n // Couchbase\n-import com.couchbase.client.java.{ CouchbaseCluster, Bucket, AsyncBucket }\n+import com.couchbase.client.java.{ CouchbaseCluster, Bucket, AsyncBucket, ConnectionString }\n import com.couchbase.client.java.env.{ CouchbaseEnvironment, DefaultCouchbaseEnvironment }\n \n-// Configuration library\n-import knobs.{ Required, Optional, FileResource, Config, ClassPathResource }\n-import java.io.File\n-import datastore.CouchDatastore\n+import datastore.{ CouchDatastore, Datastore }\n+import rx.lang.scala.JavaConversions._\n+import scala.collection.JavaConverters._\n \n /** Connect to Couchbase and execute [[db.DBProg]]s */\n final object CouchConnection {\n-  //\n-  //\n-  // Building block types for couchbase connection\n-  //\n-  //\n-\n-  private case class CouchConnectionConfig(host: String, bucketName: String, env: CouchbaseEnvironment)\n-  private case class CouchConnectionInfo(cluster: CouchbaseCluster, bucket: Bucket, env: CouchbaseEnvironment)\n-\n-  //\n-  //\n-  // Stateful connection details\n-  //\n-  //\n-  private var currentConnection: Option[CouchConnectionInfo] = None\n-  private var testConnection: Option[CouchConnectionInfo] = None\n-  val bucketOrError: Task[Bucket] = Task.delay(currentConnection.map(_.bucket).\n-    getOrElse(throw new Exception(\"Not connected\")))\n+  final val DefaultPoolSize: Int = 4\n+  final val DefaultComputationPoolSize: Int = 4\n+  final val DefaultKeyValueEndpoints: Int = 2\n+}\n \n-  //\n-  //\n-  // Configuration\n-  //\n-  //\n+final case class CouchConnection(config: DavenportConfig) {\n+  import CouchConnection._\n+  private val (environment, cluster) = createCouchbaseCluster(config)\n+  //This is only package private for testing. Use openBucket if you need a bucket.\n+  private[davenport] val openBuckets: scala.collection.concurrent.Map[BucketNameAndPassword, Bucket] = new scala.collection.concurrent.TrieMap()\n \n-  private val configFileName = \"couchbase.cfg\"\n-  private val configFileDevName = \"couchbase-dev.cfg\"\n-  private val config: Task[Config] = knobs.loadImmutable(\n-    Optional(ClassPathResource(configFileName))\n-      :: Optional(FileResource(new File(configFileDevName)))\n-      :: Nil\n-  )\n-  private val dbconfig: Task[CouchConnectionConfig] = config.map { cfg =>\n-    CouchConnectionConfig(\n-      cfg.lookup[String](\"cdb.host\") getOrElse \"couchbase.local\",\n-      cfg.lookup[String](\"cdb.bucketName\") getOrElse \"default\",\n-      DefaultCouchbaseEnvironment.builder()\n-        // .queryEnabled(cfg.lookup[Boolean](\"cdb.queryEnabled\") getOrElse false)\n-        .ioPoolSize(cfg.lookup[Int](\"cdb.ioPoolSize\") getOrElse 4)\n-        .computationPoolSize(cfg.lookup[Int](\"cdb.computationPoolSize\") getOrElse 4)\n-        .kvEndpoints(cfg.lookup[Int](\"cdb.kvEndpoints\") getOrElse 2)\n-        .build()\n-    )\n+  private final def createCouchbaseCluster(config: DavenportConfig): (CouchbaseEnvironment, CouchbaseCluster) = {\n+    val environment = DefaultCouchbaseEnvironment.builder()\n+      // .queryEnabled(cfg.lookup[Boolean](\"cdb.queryEnabled\") getOrElse false)","path":"src/main/scala/com/ironcorelabs/davenport/CouchConnection.scala","position":77,"original_position":77,"commit_id":"5c121aa8718ea8439d79062c722fdc4678c2d4aa","original_commit_id":"5c121aa8718ea8439d79062c722fdc4678c2d4aa","user":{"login":"coltfred","id":587319,"avatar_url":"https://avatars.githubusercontent.com/u/587319?v=3","gravatar_id":"","url":"https://api.github.com/users/coltfred","html_url":"https://github.com/coltfred","followers_url":"https://api.github.com/users/coltfred/followers","following_url":"https://api.github.com/users/coltfred/following{/other_user}","gists_url":"https://api.github.com/users/coltfred/gists{/gist_id}","starred_url":"https://api.github.com/users/coltfred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coltfred/subscriptions","organizations_url":"https://api.github.com/users/coltfred/orgs","repos_url":"https://api.github.com/users/coltfred/repos","events_url":"https://api.github.com/users/coltfred/events{/privacy}","received_events_url":"https://api.github.com/users/coltfred/received_events","type":"User","site_admin":false},"body":"@zmre Open an issue for this as we should add documentation as well. Line is deleted for now.","created_at":"2015-12-19T03:30:32Z","updated_at":"2015-12-19T03:30:32Z","html_url":"https://github.com/IronCoreLabs/davenport/pull/41#discussion_r48088341","pull_request_url":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/41","_links":{"self":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/comments/48088341"},"html":{"href":"https://github.com/IronCoreLabs/davenport/pull/41#discussion_r48088341"},"pull_request":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/41"}}},"pull_request":{"url":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/41","id":54070133,"html_url":"https://github.com/IronCoreLabs/davenport/pull/41","diff_url":"https://github.com/IronCoreLabs/davenport/pull/41.diff","patch_url":"https://github.com/IronCoreLabs/davenport/pull/41.patch","issue_url":"https://api.github.com/repos/IronCoreLabs/davenport/issues/41","number":41,"state":"open","locked":false,"title":"Change CouchConnection to a class","user":{"login":"coltfred","id":587319,"avatar_url":"https://avatars.githubusercontent.com/u/587319?v=3","gravatar_id":"","url":"https://api.github.com/users/coltfred","html_url":"https://github.com/coltfred","followers_url":"https://api.github.com/users/coltfred/followers","following_url":"https://api.github.com/users/coltfred/following{/other_user}","gists_url":"https://api.github.com/users/coltfred/gists{/gist_id}","starred_url":"https://api.github.com/users/coltfred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coltfred/subscriptions","organizations_url":"https://api.github.com/users/coltfred/orgs","repos_url":"https://api.github.com/users/coltfred/repos","events_url":"https://api.github.com/users/coltfred/events{/privacy}","received_events_url":"https://api.github.com/users/coltfred/received_events","type":"User","site_admin":false},"body":"- Remove knobs from being tightly coupled to CouchConnection\r\n- Add the ability to open multiple buckets\r\n- Add convenience method to open a `DataStore` from the CouchConnection\r\n- Move observable util functions to a namespace\r\nTODO - Still needs knobs for test\r\n- Manually tested that password for buckets works, but without a DDL version of the free grammar I can't test passwords because we only have default bucket in the test db.\r\n\r\nThis PR exists mainly to get feedback. Couchbase didn't seem to handle closing environments and couchbase clusters well. I tried some solutions that allowed the CouchConnection to be \"reconfigured\" on the fly, but closing the environment caused the entire app to hang for many minutes. If someone can do better, I'd welcome the help.","created_at":"2015-12-18T06:46:52Z","updated_at":"2015-12-19T03:30:32Z","closed_at":null,"merged_at":null,"merge_commit_sha":"91723507590dc15a9b41b226f0160056fdf1a15f","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/41/commits","review_comments_url":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/41/comments","review_comment_url":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/comments{/number}","comments_url":"https://api.github.com/repos/IronCoreLabs/davenport/issues/41/comments","statuses_url":"https://api.github.com/repos/IronCoreLabs/davenport/statuses/5c121aa8718ea8439d79062c722fdc4678c2d4aa","head":{"label":"coltfred:couchConnection","ref":"couchConnection","sha":"5c121aa8718ea8439d79062c722fdc4678c2d4aa","user":{"login":"coltfred","id":587319,"avatar_url":"https://avatars.githubusercontent.com/u/587319?v=3","gravatar_id":"","url":"https://api.github.com/users/coltfred","html_url":"https://github.com/coltfred","followers_url":"https://api.github.com/users/coltfred/followers","following_url":"https://api.github.com/users/coltfred/following{/other_user}","gists_url":"https://api.github.com/users/coltfred/gists{/gist_id}","starred_url":"https://api.github.com/users/coltfred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coltfred/subscriptions","organizations_url":"https://api.github.com/users/coltfred/orgs","repos_url":"https://api.github.com/users/coltfred/repos","events_url":"https://api.github.com/users/coltfred/events{/privacy}","received_events_url":"https://api.github.com/users/coltfred/received_events","type":"User","site_admin":false},"repo":{"id":41130509,"name":"davenport","full_name":"coltfred/davenport","owner":{"login":"coltfred","id":587319,"avatar_url":"https://avatars.githubusercontent.com/u/587319?v=3","gravatar_id":"","url":"https://api.github.com/users/coltfred","html_url":"https://github.com/coltfred","followers_url":"https://api.github.com/users/coltfred/followers","following_url":"https://api.github.com/users/coltfred/following{/other_user}","gists_url":"https://api.github.com/users/coltfred/gists{/gist_id}","starred_url":"https://api.github.com/users/coltfred/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/coltfred/subscriptions","organizations_url":"https://api.github.com/users/coltfred/orgs","repos_url":"https://api.github.com/users/coltfred/repos","events_url":"https://api.github.com/users/coltfred/events{/privacy}","received_events_url":"https://api.github.com/users/coltfred/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/coltfred/davenport","description":"A principled CouchBase library for Scala","fork":true,"url":"https://api.github.com/repos/coltfred/davenport","forks_url":"https://api.github.com/repos/coltfred/davenport/forks","keys_url":"https://api.github.com/repos/coltfred/davenport/keys{/key_id}","collaborators_url":"https://api.github.com/repos/coltfred/davenport/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/coltfred/davenport/teams","hooks_url":"https://api.github.com/repos/coltfred/davenport/hooks","issue_events_url":"https://api.github.com/repos/coltfred/davenport/issues/events{/number}","events_url":"https://api.github.com/repos/coltfred/davenport/events","assignees_url":"https://api.github.com/repos/coltfred/davenport/assignees{/user}","branches_url":"https://api.github.com/repos/coltfred/davenport/branches{/branch}","tags_url":"https://api.github.com/repos/coltfred/davenport/tags","blobs_url":"https://api.github.com/repos/coltfred/davenport/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/coltfred/davenport/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/coltfred/davenport/git/refs{/sha}","trees_url":"https://api.github.com/repos/coltfred/davenport/git/trees{/sha}","statuses_url":"https://api.github.com/repos/coltfred/davenport/statuses/{sha}","languages_url":"https://api.github.com/repos/coltfred/davenport/languages","stargazers_url":"https://api.github.com/repos/coltfred/davenport/stargazers","contributors_url":"https://api.github.com/repos/coltfred/davenport/contributors","subscribers_url":"https://api.github.com/repos/coltfred/davenport/subscribers","subscription_url":"https://api.github.com/repos/coltfred/davenport/subscription","commits_url":"https://api.github.com/repos/coltfred/davenport/commits{/sha}","git_commits_url":"https://api.github.com/repos/coltfred/davenport/git/commits{/sha}","comments_url":"https://api.github.com/repos/coltfred/davenport/comments{/number}","issue_comment_url":"https://api.github.com/repos/coltfred/davenport/issues/comments{/number}","contents_url":"https://api.github.com/repos/coltfred/davenport/contents/{+path}","compare_url":"https://api.github.com/repos/coltfred/davenport/compare/{base}...{head}","merges_url":"https://api.github.com/repos/coltfred/davenport/merges","archive_url":"https://api.github.com/repos/coltfred/davenport/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/coltfred/davenport/downloads","issues_url":"https://api.github.com/repos/coltfred/davenport/issues{/number}","pulls_url":"https://api.github.com/repos/coltfred/davenport/pulls{/number}","milestones_url":"https://api.github.com/repos/coltfred/davenport/milestones{/number}","notifications_url":"https://api.github.com/repos/coltfred/davenport/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/coltfred/davenport/labels{/name}","releases_url":"https://api.github.com/repos/coltfred/davenport/releases{/id}","created_at":"2015-08-21T02:46:20Z","updated_at":"2015-08-21T02:46:21Z","pushed_at":"2015-12-18T06:41:19Z","git_url":"git://github.com/coltfred/davenport.git","ssh_url":"git@github.com:coltfred/davenport.git","clone_url":"https://github.com/coltfred/davenport.git","svn_url":"https://github.com/coltfred/davenport","homepage":null,"size":232,"stargazers_count":0,"watchers_count":0,"language":"Scala","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"IronCoreLabs:master","ref":"master","sha":"cae363e0e256e212d474bdf94fa3c182b0d7fd15","user":{"login":"IronCoreLabs","id":11394047,"avatar_url":"https://avatars.githubusercontent.com/u/11394047?v=3","gravatar_id":"","url":"https://api.github.com/users/IronCoreLabs","html_url":"https://github.com/IronCoreLabs","followers_url":"https://api.github.com/users/IronCoreLabs/followers","following_url":"https://api.github.com/users/IronCoreLabs/following{/other_user}","gists_url":"https://api.github.com/users/IronCoreLabs/gists{/gist_id}","starred_url":"https://api.github.com/users/IronCoreLabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IronCoreLabs/subscriptions","organizations_url":"https://api.github.com/users/IronCoreLabs/orgs","repos_url":"https://api.github.com/users/IronCoreLabs/repos","events_url":"https://api.github.com/users/IronCoreLabs/events{/privacy}","received_events_url":"https://api.github.com/users/IronCoreLabs/received_events","type":"Organization","site_admin":false},"repo":{"id":41042360,"name":"davenport","full_name":"IronCoreLabs/davenport","owner":{"login":"IronCoreLabs","id":11394047,"avatar_url":"https://avatars.githubusercontent.com/u/11394047?v=3","gravatar_id":"","url":"https://api.github.com/users/IronCoreLabs","html_url":"https://github.com/IronCoreLabs","followers_url":"https://api.github.com/users/IronCoreLabs/followers","following_url":"https://api.github.com/users/IronCoreLabs/following{/other_user}","gists_url":"https://api.github.com/users/IronCoreLabs/gists{/gist_id}","starred_url":"https://api.github.com/users/IronCoreLabs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/IronCoreLabs/subscriptions","organizations_url":"https://api.github.com/users/IronCoreLabs/orgs","repos_url":"https://api.github.com/users/IronCoreLabs/repos","events_url":"https://api.github.com/users/IronCoreLabs/events{/privacy}","received_events_url":"https://api.github.com/users/IronCoreLabs/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/IronCoreLabs/davenport","description":"A principled CouchBase library for Scala","fork":false,"url":"https://api.github.com/repos/IronCoreLabs/davenport","forks_url":"https://api.github.com/repos/IronCoreLabs/davenport/forks","keys_url":"https://api.github.com/repos/IronCoreLabs/davenport/keys{/key_id}","collaborators_url":"https://api.github.com/repos/IronCoreLabs/davenport/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/IronCoreLabs/davenport/teams","hooks_url":"https://api.github.com/repos/IronCoreLabs/davenport/hooks","issue_events_url":"https://api.github.com/repos/IronCoreLabs/davenport/issues/events{/number}","events_url":"https://api.github.com/repos/IronCoreLabs/davenport/events","assignees_url":"https://api.github.com/repos/IronCoreLabs/davenport/assignees{/user}","branches_url":"https://api.github.com/repos/IronCoreLabs/davenport/branches{/branch}","tags_url":"https://api.github.com/repos/IronCoreLabs/davenport/tags","blobs_url":"https://api.github.com/repos/IronCoreLabs/davenport/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/IronCoreLabs/davenport/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/IronCoreLabs/davenport/git/refs{/sha}","trees_url":"https://api.github.com/repos/IronCoreLabs/davenport/git/trees{/sha}","statuses_url":"https://api.github.com/repos/IronCoreLabs/davenport/statuses/{sha}","languages_url":"https://api.github.com/repos/IronCoreLabs/davenport/languages","stargazers_url":"https://api.github.com/repos/IronCoreLabs/davenport/stargazers","contributors_url":"https://api.github.com/repos/IronCoreLabs/davenport/contributors","subscribers_url":"https://api.github.com/repos/IronCoreLabs/davenport/subscribers","subscription_url":"https://api.github.com/repos/IronCoreLabs/davenport/subscription","commits_url":"https://api.github.com/repos/IronCoreLabs/davenport/commits{/sha}","git_commits_url":"https://api.github.com/repos/IronCoreLabs/davenport/git/commits{/sha}","comments_url":"https://api.github.com/repos/IronCoreLabs/davenport/comments{/number}","issue_comment_url":"https://api.github.com/repos/IronCoreLabs/davenport/issues/comments{/number}","contents_url":"https://api.github.com/repos/IronCoreLabs/davenport/contents/{+path}","compare_url":"https://api.github.com/repos/IronCoreLabs/davenport/compare/{base}...{head}","merges_url":"https://api.github.com/repos/IronCoreLabs/davenport/merges","archive_url":"https://api.github.com/repos/IronCoreLabs/davenport/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/IronCoreLabs/davenport/downloads","issues_url":"https://api.github.com/repos/IronCoreLabs/davenport/issues{/number}","pulls_url":"https://api.github.com/repos/IronCoreLabs/davenport/pulls{/number}","milestones_url":"https://api.github.com/repos/IronCoreLabs/davenport/milestones{/number}","notifications_url":"https://api.github.com/repos/IronCoreLabs/davenport/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/IronCoreLabs/davenport/labels{/name}","releases_url":"https://api.github.com/repos/IronCoreLabs/davenport/releases{/id}","created_at":"2015-08-19T15:22:43Z","updated_at":"2015-11-05T21:35:30Z","pushed_at":"2015-12-18T06:46:52Z","git_url":"git://github.com/IronCoreLabs/davenport.git","ssh_url":"git@github.com:IronCoreLabs/davenport.git","clone_url":"https://github.com/IronCoreLabs/davenport.git","svn_url":"https://github.com/IronCoreLabs/davenport","homepage":"https://ironcorelabs.com/davenport","size":653,"stargazers_count":2,"watchers_count":2,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2,"mirror_url":null,"open_issues_count":8,"forks":2,"open_issues":8,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/41"},"html":{"href":"https://github.com/IronCoreLabs/davenport/pull/41"},"issue":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/issues/41"},"comments":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/issues/41/comments"},"review_comments":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/41/comments"},"review_comment":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/pulls/41/commits"},"statuses":{"href":"https://api.github.com/repos/IronCoreLabs/davenport/statuses/5c121aa8718ea8439d79062c722fdc4678c2d4aa"}}}}