Permalink
Browse files

initial move to github

  • Loading branch information...
1 parent 1799002 commit 499df01f72c8ccc25c9c6c691f089da65ed20bfc @DanSimon DanSimon committed Nov 11, 2014
Showing with 12,620 additions and 6 deletions.
  1. +1 −0 .gitignore
  2. +4 −4 LICENSE
  3. +33 −2 README.md
  4. +37 −0 colossus-examples/src/main/scala/colossus-examples/EchoExample.scala
  5. +59 −0 colossus-examples/src/main/scala/colossus-examples/HttpExample.scala
  6. +58 −0 colossus-examples/src/main/scala/colossus-examples/KeyValExample.scala
  7. +42 −0 colossus-examples/src/main/scala/colossus-examples/Main.scala
  8. +97 −0 colossus-examples/src/main/scala/colossus-examples/StreamExample.scala
  9. +21 −0 colossus-examples/src/main/scala/colossus-examples/TelnetExample.scala
  10. +35 −0 colossus-metrics/src/main/scala/colossus/metrics/ActorMetrics.scala
  11. +167 −0 colossus-metrics/src/main/scala/colossus/metrics/Aggregation.scala
  12. +260 −0 colossus-metrics/src/main/scala/colossus/metrics/Collection.scala
  13. +20 −0 colossus-metrics/src/main/scala/colossus/metrics/Collector.scala
  14. +140 −0 colossus-metrics/src/main/scala/colossus/metrics/Metric.scala
  15. +139 −0 colossus-metrics/src/main/scala/colossus/metrics/MetricClock.scala
  16. +4 −0 colossus-metrics/src/main/scala/colossus/metrics/MetricReport.scala
  17. +58 −0 colossus-metrics/src/main/scala/colossus/metrics/MetricSystem.scala
  18. +92 −0 colossus-metrics/src/main/scala/colossus/metrics/StatReporter.scala
  19. +70 −0 colossus-metrics/src/main/scala/colossus/metrics/TimeSeries.scala
  20. +69 −0 colossus-metrics/src/main/scala/colossus/metrics/collectors/Counter.scala
  21. +96 −0 colossus-metrics/src/main/scala/colossus/metrics/collectors/Gauge.scala
  22. +274 −0 colossus-metrics/src/main/scala/colossus/metrics/collectors/Histogram.scala
  23. +117 −0 colossus-metrics/src/main/scala/colossus/metrics/collectors/Rate.scala
  24. +175 −0 colossus-metrics/src/main/scala/colossus/metrics/package.scala
  25. +34 −0 colossus-metrics/src/main/scala/colossus/metrics/senders/LoggerSender.scala
  26. +54 −0 colossus-metrics/src/main/scala/colossus/metrics/senders/OpenTsdbSender.scala
  27. +127 −0 colossus-metrics/src/test/scala/colossus/metrics/AggregationSpec.scala
  28. +81 −0 colossus-metrics/src/test/scala/colossus/metrics/CollectionSpec.scala
  29. +82 −0 colossus-metrics/src/test/scala/colossus/metrics/GaugeSpec.scala
  30. +131 −0 colossus-metrics/src/test/scala/colossus/metrics/HistogramSpec.scala
  31. +135 −0 colossus-metrics/src/test/scala/colossus/metrics/MetricSpec.scala
  32. +27 −0 colossus-metrics/src/test/scala/colossus/metrics/RateSpec.scala
  33. +92 −0 colossus-testkit/src/main/scala/colossus-testkit/ColossusSpec.scala
  34. +29 −0 colossus-testkit/src/main/scala/colossus-testkit/FakeIOSystem.scala
  35. +73 −0 colossus-testkit/src/main/scala/colossus-testkit/HttpServiceSpec.scala
  36. +58 −0 colossus-testkit/src/main/scala/colossus-testkit/MockWriteBuffer.scala
  37. +36 −0 colossus-testkit/src/main/scala/colossus-testkit/MockWriteEndpoint.scala
  38. +62 −0 colossus-testkit/src/main/scala/colossus-testkit/ServiceSpec.scala
  39. +46 −0 colossus-testkit/src/test/scala/colossus/ServiceSpecSpec.scala
  40. +59 −0 colossus-tests/src/test/scala/colossus/Util.scala
  41. +82 −0 colossus-tests/src/test/scala/colossus/core/ActorClientSpec.scala
  42. +96 −0 colossus-tests/src/test/scala/colossus/core/AsyncHandlerSpec.scala
  43. +72 −0 colossus-tests/src/test/scala/colossus/core/ConnectionHandlerSpec.scala
  44. +49 −0 colossus-tests/src/test/scala/colossus/core/ConnectionSpec.scala
  45. +56 −0 colossus-tests/src/test/scala/colossus/core/DataBufferSpec.scala
  46. +39 −0 colossus-tests/src/test/scala/colossus/core/IOSystemSpec.scala
  47. +293 −0 colossus-tests/src/test/scala/colossus/core/ServerSpec.scala
  48. +172 −0 colossus-tests/src/test/scala/colossus/core/TaskTest.scala
  49. +65 −0 colossus-tests/src/test/scala/colossus/protocols/http/HttpHeadSpec.scala
  50. +286 −0 colossus-tests/src/test/scala/colossus/protocols/http/HttpParseSpec.scala
  51. +43 −0 colossus-tests/src/test/scala/colossus/protocols/http/HttpSpec.scala
  52. 0 colossus-tests/src/test/scala/colossus/protocols/http/UrlParsingSpec.scala
  53. +82 −0 colossus-tests/src/test/scala/colossus/protocols/http/client/HttpResponseParserSpec.scala
  54. +38 −0 colossus-tests/src/test/scala/colossus/protocols/memcache/MemcacheParserSpec.scala
  55. +40 −0 colossus-tests/src/test/scala/colossus/protocols/redis/RedisMonitorClientSpec.scala
  56. +171 −0 colossus-tests/src/test/scala/colossus/protocols/redis/RedisParserSpec.scala
  57. +34 −0 colossus-tests/src/test/scala/colossus/protocols/redis/ReplySpec.scala
  58. +79 −0 colossus-tests/src/test/scala/colossus/protocols/redis/ScatterGatherSpec.scala
  59. +53 −0 colossus-tests/src/test/scala/colossus/protocols/telnet/TelnetSpec.scala
  60. +281 −0 colossus-tests/src/test/scala/colossus/service/CallbackSpec.scala
  61. +87 −0 colossus-tests/src/test/scala/colossus/service/ClientSpec.scala
  62. +31 −0 colossus-tests/src/test/scala/colossus/service/CodecSpec.scala
  63. +131 −0 colossus-tests/src/test/scala/colossus/service/LoadBalancingClientSpec.scala
  64. +411 −0 colossus-tests/src/test/scala/colossus/service/ServiceClientSpec.scala
  65. +36 −0 colossus-tests/src/test/scala/colossus/service/ServiceDSLSpec.scala
  66. +122 −0 colossus-tests/src/test/scala/colossus/util/CombinatorSpec.scala
  67. +51 −0 colossus-tests/src/test/scala/colossus/util/ParsingTest.scala
  68. +36 −0 colossus/src/main/resources/application.conf
  69. +75 −0 colossus/src/main/scala/colossus/core/ActorHandler.scala
  70. +174 −0 colossus/src/main/scala/colossus/core/AsyncHandler.scala
  71. +216 −0 colossus/src/main/scala/colossus/core/Connection.scala
  72. +112 −0 colossus/src/main/scala/colossus/core/ConnectionHandler.scala
  73. +39 −0 colossus/src/main/scala/colossus/core/ConnectionInfo.scala
  74. +103 −0 colossus/src/main/scala/colossus/core/DataBuffer.scala
  75. +83 −0 colossus/src/main/scala/colossus/core/Delegator.scala
  76. +133 −0 colossus/src/main/scala/colossus/core/IOSystem.scala
  77. +362 −0 colossus/src/main/scala/colossus/core/Server.scala
  78. +458 −0 colossus/src/main/scala/colossus/core/Worker.scala
  79. +225 −0 colossus/src/main/scala/colossus/core/WorkerManager.scala
  80. +97 −0 colossus/src/main/scala/colossus/core/WriteBuffer.scala
  81. +49 −0 colossus/src/main/scala/colossus/metrics/JsonMetricSender.scala
  82. +162 −0 colossus/src/main/scala/colossus/protocols/http/Header.scala
  83. +16 −0 colossus/src/main/scala/colossus/protocols/http/HttpClientCodec.scala
  84. +136 −0 colossus/src/main/scala/colossus/protocols/http/HttpCode.scala
  85. +22 −0 colossus/src/main/scala/colossus/protocols/http/HttpParse.scala
  86. +46 −0 colossus/src/main/scala/colossus/protocols/http/HttpRequest.scala
  87. +35 −0 colossus/src/main/scala/colossus/protocols/http/HttpRequestParser.scala
  88. +46 −0 colossus/src/main/scala/colossus/protocols/http/HttpResponse.scala
  89. +43 −0 colossus/src/main/scala/colossus/protocols/http/HttpResponseParser.scala
  90. +16 −0 colossus/src/main/scala/colossus/protocols/http/HttpServerCodec.scala
  91. +44 −0 colossus/src/main/scala/colossus/protocols/http/UrlParsing.scala
  92. +30 −0 colossus/src/main/scala/colossus/protocols/http/package.scala
  93. +183 −0 colossus/src/main/scala/colossus/protocols/memcache/Memcache.scala
  94. +18 −0 colossus/src/main/scala/colossus/protocols/memcache/package.scala
  95. +208 −0 colossus/src/main/scala/colossus/protocols/redis/Command.scala
  96. +119 −0 colossus/src/main/scala/colossus/protocols/redis/MonitorClient.scala
  97. +16 −0 colossus/src/main/scala/colossus/protocols/redis/RedisClientCodec.scala
  98. +27 −0 colossus/src/main/scala/colossus/protocols/redis/RedisCommandParser.scala
  99. +59 −0 colossus/src/main/scala/colossus/protocols/redis/RedisReplyParser.scala
  100. +17 −0 colossus/src/main/scala/colossus/protocols/redis/RedisServerCodec.scala
  101. +71 −0 colossus/src/main/scala/colossus/protocols/redis/Reply.scala
  102. +137 −0 colossus/src/main/scala/colossus/protocols/redis/ScatterGather.scala
  103. +118 −0 colossus/src/main/scala/colossus/protocols/redis/UnifiedProtocol.scala
  104. +72 −0 colossus/src/main/scala/colossus/protocols/redis/package.scala
  105. +127 −0 colossus/src/main/scala/colossus/protocols/telnet/Telnet.scala
  106. +147 −0 colossus/src/main/scala/colossus/service/AsyncServiceClient.scala
  107. +317 −0 colossus/src/main/scala/colossus/service/Callback.scala
  108. +150 −0 colossus/src/main/scala/colossus/service/Codec.scala
  109. +176 −0 colossus/src/main/scala/colossus/service/LoadBalancingClient.scala
  110. +373 −0 colossus/src/main/scala/colossus/service/ServiceClient.scala
  111. +48 −0 colossus/src/main/scala/colossus/service/ServiceClientPool.scala
  112. +280 −0 colossus/src/main/scala/colossus/service/ServiceDSL.scala
  113. +247 −0 colossus/src/main/scala/colossus/service/ServiceServer.scala
  114. +9 −0 colossus/src/main/scala/colossus/service/package.scala
  115. +568 −0 colossus/src/main/scala/colossus/util/Parsing.scala
  116. +141 −0 colossus/src/main/scala/colossus/util/Task.scala
  117. +78 −0 project/Build.scala
  118. +50 −0 project/Publish.scala
  119. +3 −0 project/build.properties
  120. +9 −0 project/plugins.sbt
View
@@ -1,5 +1,6 @@
*.class
*.log
+*.swp
# sbt specific
.cache/
View
@@ -1,4 +1,5 @@
-Apache License
+
+ Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
@@ -178,15 +179,15 @@ Apache License
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
+ boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright {yyyy} {name of copyright owner}
+ Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -199,4 +200,3 @@ Apache License
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-
View
@@ -1,2 +1,33 @@
-colossus
-========
+Colossus
+=========
+
+_Heads up! We're just getting setup. Published artifacts may not be available yet._
+
+Colossus is a lightweight I/O framework for building scala services.
+
+Full documentation can be found here : http://tumblr.github.io/colossus
+
+Here's an overview of what you can find in this repo
+
+* `colossus` : The framework
+* `colossus-metrics` : high-performance metrics library (does not depend on colossus)
+* `colossus-examples` : A few simple examples that can be run
+* `colossus-testkit` : Small library containing a few useful tools for testing
+* `colossus-tests` : The unit and integration tests for colossus
+
+### License
+
+Copyright 2014 Tumblr Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
@@ -0,0 +1,37 @@
+package colossus.examples
+
+import colossus.IOSystem
+import colossus.core._
+
+/*
+ * The BasicSyncHandler is a ConnectionHandler that has has default
+ * implementations for most of the methods. It also stores the WriteEndpoint
+ * that is passed in the connected method.
+ */
+class EchoHandler extends BasicSyncHandler {
+ def receivedData(data: DataBuffer){
+ endpoint.write(data)
+ }
+}
+
+class EchoDelegator(server: ServerRef, worker: WorkerRef) extends Delegator(server, worker) {
+
+ def acceptNewConnection = Some(new EchoHandler)
+}
+
+object EchoExample {
+
+ def start(port: Int)(implicit io: IOSystem): ServerRef = {
+ val echoConfig = ServerConfig(
+ name = "echo",
+ settings = ServerSettings(
+ port = port
+ ),
+ delegatorFactory = (server, worker) => new EchoDelegator(server, worker)
+ )
+ Server(echoConfig)
+
+ }
+
+}
+
@@ -0,0 +1,59 @@
+package colossus.examples
+
+import akka.util.ByteString
+import colossus.IOSystem
+import colossus.core.ServerRef
+import colossus.protocols.http._
+import colossus.protocols.redis._
+import colossus.service.{LocalClient, Service, Response}
+import java.net.InetSocketAddress
+
+import UrlParsing._
+import HttpMethod._
+import UnifiedProtocol._
+
+
+object HttpExample {
+
+ /**
+ * Here we're demonstrating a common way of breaking out the business logic
+ * from the server setup, which makes functional testing easy
+ */
+ class HttpRoutes(redis: LocalClient[Command, Reply]) {
+
+ def invalidReply(reply: Reply) = s"Invalid reply from redis $reply"
+
+ val handler: PartialFunction[HttpRequest, Response[HttpResponse]] = {
+ case req @ Get on Root => req.ok("Hello World!")
+
+ case req @ Get on Root / "get" / key => redis.send(Commands.Get(ByteString(key))).map{
+ case BulkReply(data) => req.ok(data.utf8String)
+ case NilReply => req.notFound("(nil)")
+ case other => req.error(invalidReply(other))
+ }
+
+ case req @ Get on Root / "set" / key / value => redis.send(Commands.Set(ByteString(key), ByteString(value))).map{
+ case StatusReply(msg) => req.ok(msg)
+ case other => req.error(invalidReply(other))
+ }
+
+ }
+
+ }
+
+
+ def start(port: Int, redisAddress: InetSocketAddress)(implicit system: IOSystem): ServerRef = {
+ Service.serve[Http]("http-example", port){context =>
+ val redis = context.clientFor[Redis](redisAddress.getHostName, redisAddress.getPort)
+ //because our routes object has no internal state, we can share it among
+ //connections. If the class did have some per-connection internal state,
+ //we'd just create one per connection
+ val routes = new HttpRoutes(redis)
+
+ context.handle{connection =>
+ connection.become(routes.handler)
+ }
+ }
+ }
+
+}
@@ -0,0 +1,58 @@
+package colossus.examples
+
+import akka.actor._
+import akka.util.ByteString
+import colossus.IOSystem
+import colossus.core.ServerRef
+import colossus.service._
+import colossus.protocols.redis._
+import scala.concurrent.{Promise, Future}
+import UnifiedProtocol._
+
+class KeyValDB extends Actor {
+
+ import KeyValDB._
+
+ val db = collection.mutable.Map[ByteString, ByteString]()
+
+ def receive = {
+ case Get(key, promise) => promise.success(db.get(key))
+ case Set(key, value, promise) => {
+ db(key) = value
+ promise.success(())
+ }
+ }
+}
+
+object KeyValDB {
+ case class Get(key: ByteString, promise: Promise[Option[ByteString]] = Promise())
+ case class Set(key: ByteString, value: ByteString, promise: Promise[Unit] = Promise())
+}
+
+object KeyValExample {
+
+ def start(port: Int)(implicit io: IOSystem): ServerRef = {
+ import io.actorSystem.dispatcher
+
+ val db = io.actorSystem.actorOf(Props[KeyValDB])
+
+ Service.become[Redis]("key-value-example", port){
+ case Command("GET", args) => {
+ val dbCmd = KeyValDB.Get(args(0))
+ db ! dbCmd
+ dbCmd.promise.future.map{
+ case Some(value) => BulkReply(value)
+ case None => NilReply
+ }
+ }
+ case Command("SET", args) => {
+ val dbCmd = KeyValDB.Set(args(0), args(1))
+ db ! dbCmd
+ dbCmd.promise.future.map{_ =>
+ StatusReply("OK")
+ }
+ }
+ }
+ }
+}
+
@@ -0,0 +1,42 @@
+package colossus.examples
+
+import colossus._
+import akka.actor._
+import java.net.InetSocketAddress
+
+
+
+object Main extends App {
+
+ override def main(args: Array[String]) {
+ println(""" _______ _______ _ _______ _______ _______ _______ """)
+ println("""( ____ \( ___ )( \ ( ___ )( ____ \( ____ \|\ /|( ____ \""")
+ println("""| ( \/| ( ) || ( | ( ) || ( \/| ( \/| ) ( || ( \/""")
+ println("""| | | | | || | | | | || (_____ | (_____ | | | || (_____ """)
+ println("""| | | | | || | | | | |(_____ )(_____ )| | | |(_____ )""")
+ println("""| | | | | || | | | | | ) | ) || | | | ) |""")
+ println("""| (____/\| (___) || (____/\| (___) |/\____) |/\____) || (___) |/\____) |""")
+ println("""(_______/(_______)(_______/(_______)\_______)\_______)(_______)\_______)""")
+
+ implicit val actorSystem = ActorSystem("COLOSSUS")
+
+ implicit val ioSystem = IOSystem("examples", numWorkers = Some(4), statsPort = Some(8080))
+
+ //the simplest example, an echo server over telnet
+ val telnetServer = TelnetExample.start(9000)
+
+ //http service which communicates with a key/value store over the redis protocol
+ val httpServer = HttpExample.start(9001, new InetSocketAddress("localhost", 9002))
+
+ //and here's the key/value store itself
+ val keyvalServer = KeyValExample.start(9002)
+
+ //an echo server built only on the core layer
+ val echoServer = EchoExample.start(9003)
+
+ //a simple firehose using the Actor API
+ val streamServer = StreamExample.start(9004)
+
+ }
+
+}
@@ -0,0 +1,97 @@
+package colossus.examples
+
+import colossus.IOSystem
+import colossus.core._
+
+import akka.actor._
+import akka.util.ByteString
+import scala.concurrent.duration._
+
+class MessageProvider extends Actor {
+ import MessageProvider._
+ import context.dispatcher
+ var num = 0
+ def receive = {
+ case NextMessage => {
+ context.system.scheduler.scheduleOnce(500.milliseconds, sender, s"message_$num")
+ num += 1
+ }
+ }
+}
+object MessageProvider {
+ case object NextMessage
+}
+
+class StreamDelegator(provider: ActorRef, server: ServerRef, worker: WorkerRef) extends Delegator(server, worker) {
+ var id = 0
+ def nextId = {id += 1;id}
+ implicit val workerRef: ActorRef = worker.worker
+ def acceptNewConnection = {
+ val handler = server.system.actorSystem.actorOf(Props(classOf[StreamWorker], provider))
+ Some(AsyncHandler.serverHandler(handler, worker)(server.system.actorSystem))
+ }
+}
+
+class StreamWorker(provider: ActorRef) extends Actor with ActorLogging {
+ import ConnectionEvent._
+ import ConnectionCommand._
+ import MessageProvider._
+
+ def receive = {
+ case Connected(id) => {
+ context.become(alive(sender))
+ provider ! NextMessage
+ }
+ }
+
+ def alive(connection: ActorRef): Receive = {
+ case message: String => {
+ connection ! Write(ByteString(message + "\r\n"), AckLevel.AckAll)
+ }
+ case WriteAck(WriteStatus.Complete) => provider ! NextMessage
+ case WriteAck(WriteStatus.Partial) => context.become(overflow(connection))
+ case WriteAck(WriteStatus.Zero) => context.become(overflow(connection))
+ case WriteAck(WriteStatus.Failed) => {
+ log.error("Failed to write")
+ context stop self
+ }
+
+ case ConnectionTerminated(cause) => {
+ log.info(s"Connection Closed: $cause")
+ context stop self
+ }
+ }
+
+ def overflow(connection: ActorRef): Receive = {
+ case ReadyForData => {
+ provider ! NextMessage
+ context.become(alive(connection))
+ }
+ case ConnectionTerminated(cause) => {
+ context stop self
+ }
+ }
+
+
+}
+
+object StreamExample {
+
+ def start(port: Int)(implicit io: IOSystem): ServerRef = {
+ //stream example
+ val provider = io.actorSystem.actorOf(Props[MessageProvider], name = "stream-provider")
+ val streamConfig = ServerConfig(
+ name = "stream",
+ settings = ServerSettings(
+ port = port,
+ maxIdleTime = Duration.Inf
+ ),
+ delegatorFactory = (s, a) => new StreamDelegator(provider, s, a)
+ )
+
+ Server(streamConfig)
+ }
+
+
+}
+
@@ -0,0 +1,21 @@
+package colossus.examples
+
+import colossus.IOSystem
+import colossus.core.{ServerRef}
+import colossus.service._
+import colossus.protocols.telnet._
+
+
+object TelnetExample {
+
+ def start(port: Int)(implicit io: IOSystem): ServerRef = {
+
+ Service.become[Telnet]("telnet-test", port) {
+ case TelnetCommand("exit" :: Nil) => TelnetReply("Bye!").onWrite(OnWriteAction.Disconnect)
+ case TelnetCommand(List("say", arg)) => TelnetReply(arg)
+ case other => TelnetReply(other.toString)
+ }
+
+ }
+}
+
Oops, something went wrong.

0 comments on commit 499df01

Please sign in to comment.