Skip to content

Commit 75a7cbd

Browse files
committed
Merge branch 'release/0.10.0'
2 parents 7046e90 + cbaabbe commit 75a7cbd

File tree

24 files changed

+394
-108
lines changed

24 files changed

+394
-108
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: scala
2+
sudo: false
23
scala:
34
- 2.10.4
4-
- 2.9.3
55
before_script:
66
- mysql -u root -e "create database storehaus_test;"
77
- mysql -u root -e "create user 'storehaususer'@'localhost' identified by 'test1234';"

CHANGES.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
# Storehaus #
22

3+
### Version 0.10.0 ###
4+
* Use latest scalding, algebird, and bijection versions: https://github.com/twitter/storehaus/pull/255
5+
* Use new Travis CI container infrastructure: https://github.com/twitter/storehaus/pull/254
6+
* Add hook for CAS based memcache mergeable: https://github.com/twitter/storehaus/pull/252
7+
* Bump bijection/algebird versions: https://github.com/twitter/storehaus/pull/253
8+
* Remove + operator: https://github.com/twitter/storehaus/pull/21
9+
* Memcache mergeable - use semigroup: https://github.com/twitter/storehaus/pull/251
10+
* add logic for replicating writes and reads to stores: https://github.com/twitter/storehaus/pull/20
11+
* bump finagle and util to 6.22.0: https://github.com/twitter/storehaus/pull/247
12+
* Minified kill 2.9.3: https://github.com/twitter/storehaus/pull/249
13+
* Read through store - do not query backing store when no cache miss: https://github.com/twitter/storehaus/pull/246
14+
* implementation of store that uses http protocol: https://github.com/twitter/storehaus/pull/241
15+
* Retry unittest: https://github.com/twitter/storehaus/pull/240
16+
* Added endpoint support to storehaus-dynamodb: https://github.com/twitter/storehaus/pull/236
17+
* Https sonatype: https://github.com/twitter/storehaus/pull/237
18+
319
### Version 0.9.1 ###
420
* Feature/write through cache perf: https://github.com/twitter/storehaus/pull/234
521
* Share the Retrying Read Write store in storehaus repo: https://github.com/twitter/storehaus/pull/230

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ Here's a list of modules we plan in implementing, with links to the github issue
9898

9999
## Community and Documentation
100100

101+
This, and all [github.com/twitter](https://github.com/twitter) projects, are under the [Twitter Open Source Code of Conduct](https://engineering.twitter.com/opensource/code-of-conduct). Additionally, see the [Typelevel Code of Conduct](http://typelevel.org/conduct) for specific examples of harassing behavior that are not tolerated.
102+
101103
To learn more and find links to tutorials and information around the web, check out the [Storehaus Wiki](https://github.com/twitter/storehaus/wiki).
102104

103105
The latest ScalaDocs are hosted on Storehaus's [Github Project Page](http://twitter.github.io/storehaus).
@@ -106,7 +108,7 @@ Discussion occurs primarily on the [Storehaus mailing list](https://groups.googl
106108

107109
## Maven
108110

109-
Storehaus modules are available on maven central. The current groupid and version for all modules is, respectively, `"com.twitter"` and `0.9.0`.
111+
Storehaus modules are available on maven central. The current groupid and version for all modules is, respectively, `"com.twitter"` and `0.10.0`.
110112

111113
Current published artifacts are
112114

project/Build.scala

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,9 @@ object StorehausBuild extends Build {
5757

5858
val sharedSettings = extraSettings ++ ciSettings ++ Seq(
5959
organization := "com.twitter",
60-
scalaVersion := "2.9.3",
61-
version := "0.9.1",
62-
crossScalaVersions := Seq("2.9.3", "2.10.4"),
60+
scalaVersion := "2.10.4",
61+
version := "0.10.0",
62+
crossScalaVersions := Seq("2.10.4"),
6363
javacOptions ++= Seq("-source", "1.6", "-target", "1.6"),
6464
javacOptions in doc := Seq("-source", "1.6"),
6565
libraryDependencies <+= scalaVersion(specs2Import(_)),
@@ -117,14 +117,14 @@ object StorehausBuild extends Build {
117117
def youngestForwardCompatible(subProj: String) =
118118
Some(subProj)
119119
.filterNot(unreleasedModules.contains(_))
120-
.map { s => "com.twitter" % ("storehaus-" + s + "_2.9.3") % "0.9.0" }
121-
122-
val algebirdVersion = "0.7.0"
123-
val bijectionVersion = "0.6.3"
124-
val utilVersion = "6.11.0"
125-
val scaldingVersion = "0.11.1"
120+
.map { s => "com.twitter" % ("storehaus-" + s + "_2.10") % "0.10.0" }
126121

122+
val algebirdVersion = "0.9.0"
123+
val bijectionVersion = "0.7.2"
124+
val utilVersion = "6.22.0"
125+
val scaldingVersion = "0.13.1"
127126
lazy val storehaus = Project(
127+
128128
id = "storehaus",
129129
base = file("."),
130130
settings = sharedSettings ++ DocGen.publishSettings
@@ -145,6 +145,7 @@ object StorehausBuild extends Build {
145145
storehausKafka08,
146146
storehausMongoDB,
147147
storehausElastic,
148+
storehausHttp,
148149
storehausTesting
149150
)
150151

@@ -292,4 +293,12 @@ object StorehausBuild extends Build {
292293
javaOptions in run <++= (fullClasspath in Runtime) map { cp => Seq("-cp", sbt.Build.data(cp).mkString(":")) }
293294
).dependsOn(storehausCore, storehausAlgebra, storehausCache)
294295

296+
lazy val storehausHttp = module("http").settings(
297+
libraryDependencies ++= Seq(
298+
Finagle.module("http"),
299+
"com.twitter" %% "bijection-netty" % bijectionVersion
300+
)
301+
).dependsOn(storehausCore)
302+
303+
295304
}

project/Finagle.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package storehaus
55
* dependency */
66
object Finagle {
77
import sbt._
8-
val LatestVersion = "6.12.2"
8+
val LatestVersion = "6.22.0"
99
def module(name: String, version: String = LatestVersion) =
1010
StorehausBuild.withCross("com.twitter" %% "finagle-%s".format(name) % version)
1111
}

project/build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
sbt.version=0.13.0
1+
sbt.version=0.13.5

project/plugins.sbt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
resolvers ++= Seq(
22
"jgit-repo" at "http://download.eclipse.org/jgit/maven",
3-
"sonatype-releases" at "http://oss.sonatype.org/content/repositories/releases"
3+
"sonatype-releases" at "https://oss.sonatype.org/content/repositories/releases"
44
)
55

66
addSbtPlugin("com.typesafe.sbt" % "sbt-ghpages" % "0.5.1")
@@ -9,4 +9,4 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.1.6")
99

1010
addSbtPlugin("io.spray" % "sbt-boilerplate" % "0.5.1")
1111

12-
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")
12+
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.11.2")

sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Author: Paul Phillips <paulp@typesafe.com>
55

66
# todo - make this dynamic
7-
declare -r sbt_release_version=0.13.0
7+
declare -r sbt_release_version=0.13.5
88

99
declare sbt_jar sbt_dir sbt_create sbt_launch_dir
1010
declare scala_version java_home sbt_explicit_version

storehaus-cache/src/main/scala/com/twitter/storehaus/cache/CyclicIncrement.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class CyclicIncrementProvider[@specialized(Int, Long) K: Successible]
5959
nextSideCount: Int,
6060
maxNextSideVal: K) extends IdProvider[CyclicIncrement[K]] {
6161

62-
implicit val ord = implicitly[Successible[K]].ordering
62+
implicit val ord = implicitly[Successible[K]].partialOrdering
6363
private def next(v: K) =
6464
Successible.next(v).getOrElse(throw new IllegalStateException("Hit maximum value for increment"))
6565

storehaus-cache/src/main/scala/com/twitter/storehaus/cache/HHFilteredCache.scala

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package com.twitter.storehaus.cache
1818

19-
import com.twitter.algebird.{ Semigroup, Monoid, Group, CMSHash }
19+
import com.twitter.algebird.{ Semigroup, Monoid, Group, CMSHash, CMSHasherImplicits}
2020
import com.twitter.util.Future
2121

2222

@@ -41,6 +41,8 @@ object HeavyHittersPercent {
4141
}
4242

4343
sealed class ApproxHHTracker[K](hhPct: HeavyHittersPercent, updateFreq: WriteOperationUpdateFrequency, roFreq: RollOverFrequencyMS) {
44+
import CMSHasherImplicits._
45+
4446
private[this] final val WIDTH = 1000
4547
private[this] final val DEPTH = 4
4648
private[this] final val hh = new java.util.HashMap[K, Long]()
@@ -53,9 +55,9 @@ sealed class ApproxHHTracker[K](hhPct: HeavyHittersPercent, updateFreq: WriteOpe
5355
private[this] var nextRollOver: Long = System.currentTimeMillis + roFreq.toLong
5456
private[this] final val updateOps = new java.util.concurrent.atomic.AtomicInteger(0)
5557

56-
private[this] final val hashes: IndexedSeq[CMSHash] = {
58+
private[this] final val hashes: IndexedSeq[CMSHash[Long]] = {
5759
val r = new scala.util.Random(5)
58-
(0 until DEPTH).map { _ => CMSHash(r.nextInt, 0, WIDTH) }
60+
(0 until DEPTH).map { _ => CMSHash[Long](r.nextInt, 0, WIDTH) }
5961
}.toIndexedSeq
6062

6163
@inline

storehaus-core/src/main/scala/com/twitter/storehaus/ReadThroughStore.scala

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,17 @@ class ReadThroughStore[K, V](backingStore: ReadableStore[K, V], cache: Store[K,
7272
val hits = responses.filter { !_._2.isEmpty }
7373
val missedKeys = responses.filter { _._2.isEmpty }.keySet
7474

75-
FutureOps.mapCollect(backingStore.multiGet(missedKeys ++ failedKeys)).flatMap { storeResult =>
76-
// write fetched keys to cache, best effort
77-
mutex.acquire.flatMap { p =>
78-
FutureOps.mapCollect(cache.multiPut(storeResult))(FutureCollector.bestEffort[(K1, Unit)])
79-
.map { u => hits ++ storeResult }
80-
.ensure { p.release }
75+
val remaining = missedKeys ++ failedKeys
76+
if (remaining.isEmpty) {
77+
Future.value(hits) // no cache misses
78+
} else {
79+
FutureOps.mapCollect(backingStore.multiGet(remaining)).flatMap { storeResult =>
80+
// write fetched keys to cache, best effort
81+
mutex.acquire.flatMap { p =>
82+
FutureOps.mapCollect(cache.multiPut(storeResult))(FutureCollector.bestEffort[(K1, Unit)])
83+
.map { u => hits ++ storeResult }
84+
.ensure { p.release }
85+
}
8186
}
8287
}
8388
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2014 Twitter Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
5+
* not use this file except in compliance with the License. You may obtain
6+
* a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.twitter.storehaus
18+
19+
import com.twitter.conversions.time._
20+
import com.twitter.util.{JavaTimer, Timer}
21+
22+
import org.scalacheck.Properties
23+
24+
object RetryingStoreProperties extends Properties("RetryingStore") {
25+
import StoreProperties.storeTest
26+
27+
implicit val timer: Timer = new JavaTimer(true)
28+
29+
property("RetryingStore obeys the Store laws, assuming the underlying Store always returns results before timeout") =
30+
storeTest[String, Int] {
31+
Store.withRetry[String, Int](
32+
store = new ConcurrentHashMapStore[String,Int](),
33+
backoffs = for (i <- 0 until 3) yield 1.milliseconds
34+
)(_ => true)
35+
}
36+
}

storehaus-dynamodb/src/main/scala/com/twitter/storehaus/dynamodb/DynamoLongStore.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,18 @@ import com.twitter.storehaus.ConvertedStore
2424
import com.twitter.storehaus.algebra.MergeableStore
2525

2626
import scala.util.Try
27-
27+
import com.amazonaws.regions.{ Region, Regions }
2828
import com.amazonaws.services.dynamodbv2.model._
2929

3030
import AwsBijections._
3131

3232
object DynamoLongStore {
33-
def apply(awsAccessKey: String, awsSecretKey: String, tableName: String, primaryKeyColumn: String, valueColumn: String) =
34-
new DynamoLongStore(DynamoStore(awsAccessKey, awsSecretKey, tableName, primaryKeyColumn, valueColumn))
33+
def apply(awsAccessKey: String, awsSecretKey: String, tableName: String,
34+
primaryKeyColumn: String, valueColumn: String,
35+
endpoint: Regions = Regions.US_EAST_1) =
36+
37+
new DynamoLongStore(DynamoStore(awsAccessKey, awsSecretKey, tableName,
38+
primaryKeyColumn, valueColumn, endpoint))
3539
}
3640

3741
class DynamoLongStore(underlying: DynamoStore)

storehaus-dynamodb/src/main/scala/com/twitter/storehaus/dynamodb/DynamoStore.scala

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import com.twitter.util.{ Future, FuturePool }
2323
import com.twitter.storehaus.Store
2424

2525
import com.amazonaws.auth.BasicAWSCredentials
26+
import com.amazonaws.regions.{ Region, Regions }
2627
import com.amazonaws.services.dynamodbv2.{ AmazonDynamoDBClient, AmazonDynamoDB }
2728
import com.amazonaws.services.dynamodbv2.model._
2829

@@ -34,19 +35,25 @@ import AwsBijections._
3435

3536
object DynamoStore {
3637

37-
def apply(awsAccessKey: String, awsSecretKey: String, tableName: String, primaryKeyColumn: String, valueColumn: String): DynamoStore = {
38+
def apply(awsAccessKey: String, awsSecretKey: String, tableName: String,
39+
primaryKeyColumn: String, valueColumn: String,
40+
endpoint: Regions = Regions.US_EAST_1): DynamoStore = {
41+
3842
val processors = Runtime.getRuntime.availableProcessors
39-
this(awsAccessKey, awsSecretKey, tableName, primaryKeyColumn, valueColumn, processors)
43+
this(awsAccessKey, awsSecretKey, tableName, primaryKeyColumn, valueColumn,
44+
processors, endpoint)
4045
}
4146

4247
def apply(awsAccessKey: String, awsSecretKey: String, tableName: String,
43-
primaryKeyColumn: String, valueColumn: String, numberWorkerThreads: Int): DynamoStore = {
48+
primaryKeyColumn: String, valueColumn: String, numberWorkerThreads: Int,
49+
endpoint: Regions): DynamoStore = {
4450

4551
val auth = new BasicAWSCredentials(awsAccessKey, awsSecretKey)
46-
val client = new AmazonDynamoDBClient(auth)
47-
new DynamoStore(client, tableName, primaryKeyColumn, valueColumn, numberWorkerThreads)
52+
var client = new AmazonDynamoDBClient(auth)
53+
client.setRegion(Region.getRegion(endpoint));
54+
new DynamoStore(client, tableName, primaryKeyColumn, valueColumn,
55+
numberWorkerThreads)
4856
}
49-
5057
}
5158

5259
class DynamoStore(val client: AmazonDynamoDB, val tableName: String,
@@ -75,9 +82,7 @@ class DynamoStore(val client: AmazonDynamoDB, val tableName: String,
7582

7683
apiRequestFuturePool(client.deleteItem(deleteRequest))
7784
}
78-
7985
}
80-
8186
}
8287

8388
override def get(k: String): Future[Option[AttributeValue]] = {
@@ -88,6 +93,4 @@ class DynamoStore(val client: AmazonDynamoDB, val tableName: String,
8893
Option(client.getItem(getRequest).getItem).map(_.get(valueColumn))
8994
}
9095
}
91-
9296
}
93-

storehaus-dynamodb/src/main/scala/com/twitter/storehaus/dynamodb/DynamoStringStore.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@ import java.util.{ Map => JMap }
1919

2020
import com.twitter.storehaus.ConvertedStore
2121

22+
import com.amazonaws.regions.{ Region, Regions }
2223
import com.amazonaws.services.dynamodbv2.model._
2324

2425
import AwsBijections._
2526

2627
object DynamoStringStore {
27-
def apply(awsAccessKey: String, awsSecretKey: String, tableName: String, primaryKeyColumn: String, valueColumn: String) =
28-
new DynamoStringStore(DynamoStore(awsAccessKey, awsSecretKey, tableName, primaryKeyColumn, valueColumn))
28+
def apply(awsAccessKey: String, awsSecretKey: String, tableName: String,
29+
primaryKeyColumn: String, valueColumn: String,
30+
endpoint: Regions = Regions.US_EAST_1) =
31+
32+
new DynamoStringStore(DynamoStore(awsAccessKey, awsSecretKey, tableName,
33+
primaryKeyColumn, valueColumn, endpoint))
2934
}
3035

3136
class DynamoStringStore(underlying: DynamoStore)

storehaus-elasticsearch/src/test/scala/com/twitter/storehaus/elasticsearch/ElasticSearchStoreSpecs.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import org.json4s.{native, NoTypeHints}
2929
* @since 1/13/14
3030
*/
3131
class ElasticSearchStoreSpecs extends Specification {
32+
sequential
33+
3234
private implicit val formats = native.Serialization.formats(NoTypeHints)
3335

3436
private val person = Person("Joe", "Smith", 29)

0 commit comments

Comments
 (0)