Skip to content

Commit e71181a

Browse files
jakubjanecekmergify[bot]
authored andcommitted
feat: Add grpc-server module with PureConfig integration (#104)
* feat: Add grpc-server module with PureConfig integration * fix: Disable WartRemover NonUnitStatements (false positive) * refactor: Rename method arg
1 parent 0bd162b commit e71181a

File tree

6 files changed

+113
-0
lines changed

6 files changed

+113
-0
lines changed

build.sbt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ lazy val root = project
2727
example,
2828
flyway,
2929
flywayPureConfig,
30+
grpcServer,
31+
grpcServerPureConfig,
3032
http4sClientBlaze,
3133
http4sClientBlazePureConfig,
3234
http4sClientMonixCatnap,
@@ -168,6 +170,27 @@ lazy val flywayPureConfig = project
168170
libraryDependencies += Dependencies.pureConfig
169171
)
170172

173+
lazy val grpcServer = project
174+
.in(file("grpc-server"))
175+
.settings(commonSettings)
176+
.settings(
177+
name := "sst-grpc-server",
178+
libraryDependencies ++= Seq(
179+
Dependencies.grpcNettyShaded,
180+
Dependencies.grpcProtobuf,
181+
Dependencies.grpcStub
182+
)
183+
)
184+
185+
lazy val grpcServerPureConfig = project
186+
.in(file("grpc-server-pureconfig"))
187+
.dependsOn(grpcServer)
188+
.settings(commonSettings)
189+
.settings(
190+
name := "sst-grpc-server-pureconfig",
191+
libraryDependencies += Dependencies.pureConfig
192+
)
193+
171194
lazy val http4sClientBlaze = project
172195
.in(file("http4s-client-blaze"))
173196
.settings(commonSettings)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.avast.sst.grpc.server.pureconfig
2+
3+
import com.avast.sst.grpc.server.GrpcServerConfig
4+
import pureconfig.ConfigReader
5+
import pureconfig.generic.semiauto.deriveReader
6+
7+
trait ConfigReaders {
8+
9+
implicit val grpcServerGrpcServerConfigReader: ConfigReader[GrpcServerConfig] = deriveReader
10+
11+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.avast.sst.grpc.server.pureconfig
2+
3+
import pureconfig.ConfigFieldMapping
4+
import pureconfig.generic.ProductHint
5+
6+
/** Contains [[pureconfig.ConfigReader]] instances with default "kebab-case" naming convention. */
7+
object implicits extends ConfigReaders {
8+
9+
/** Contains [[pureconfig.ConfigReader]] instances with "kebab-case" naming convention.
10+
*
11+
* This is alias for the default `implicits._` import.
12+
*/
13+
object KebabCase extends ConfigReaders
14+
15+
/** Contains [[pureconfig.ConfigReader]] instances with "camelCase" naming convention. */
16+
object CamelCase extends ConfigReaders {
17+
implicit def hint[T]: ProductHint[T] = ProductHint(ConfigFieldMapping(pureconfig.CamelCase, pureconfig.CamelCase))
18+
}
19+
20+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.avast.sst.grpc.server
2+
3+
import java.util.concurrent.TimeUnit
4+
5+
import scala.concurrent.duration.Duration
6+
7+
final case class GrpcServerConfig(port: Int,
8+
handshakeTimeout: Duration,
9+
maxInboundMessageSize: Int = 4 * 1024 * 1024,
10+
maxInboundMetadataSize: Int = 8192,
11+
serverShutdownTimeout: Duration = Duration(10, TimeUnit.SECONDS))
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package com.avast.sst.grpc.server
2+
3+
import java.util.concurrent.TimeUnit
4+
5+
import cats.effect.{Resource, Sync}
6+
import io.grpc.{Server, ServerBuilder, ServerInterceptor, ServerServiceDefinition}
7+
8+
import scala.collection.immutable.Seq
9+
import scala.concurrent.ExecutionContext
10+
object GrpcServerModule {
11+
12+
/** Makes [[io.grpc.Server]] (Netty) initialized with the given config, services and interceptors.
13+
*
14+
* @param services service implementations to be added to the handler registry
15+
* @param executionContext executor to be used for the server
16+
* @param interceptors that are run for all the services
17+
*/
18+
@SuppressWarnings(Array("org.wartremover.warts.NonUnitStatements"))
19+
def make[F[_]: Sync](config: GrpcServerConfig,
20+
services: Seq[ServerServiceDefinition],
21+
executionContext: ExecutionContext,
22+
interceptors: Seq[ServerInterceptor] = List.empty): Resource[F, Server] =
23+
Resource.make {
24+
Sync[F].delay {
25+
val builder = ServerBuilder
26+
.forPort(config.port)
27+
.handshakeTimeout(config.handshakeTimeout.toMillis, TimeUnit.MILLISECONDS)
28+
.maxInboundMessageSize(config.maxInboundMessageSize)
29+
.maxInboundMetadataSize(config.maxInboundMetadataSize)
30+
.executor(executionContext.execute)
31+
32+
services.foreach(builder.addService)
33+
interceptors.foreach(builder.intercept)
34+
35+
builder.build.start()
36+
}
37+
} { s =>
38+
Sync[F].delay {
39+
s.shutdown().awaitTermination(config.serverShutdownTimeout.toMillis, TimeUnit.MILLISECONDS)
40+
()
41+
}
42+
}
43+
44+
}

project/Dependencies.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ object Dependencies {
77
val doobie = "org.tpolecat" %% "doobie-core" % Versions.doobie
88
val doobieHikari = "org.tpolecat" %% "doobie-hikari" % Versions.doobie
99
val flywayCore = "org.flywaydb" % "flyway-core" % "6.1.2"
10+
val grpcNettyShaded = "io.grpc" % "grpc-netty-shaded" % Versions.grpc
11+
val grpcProtobuf = "io.grpc" % "grpc-protobuf" % Versions.grpc
12+
val grpcStub = "io.grpc" % "grpc-stub" % Versions.grpc
1013
val http4sBlazeClient = "org.http4s" %% "http4s-blaze-client" % Versions.http4s
1114
val http4sBlazeServer = "org.http4s" %% "http4s-blaze-server" % Versions.http4s
1215
val http4sClient = "org.http4s" %% "http4s-client" % Versions.http4s
@@ -35,6 +38,7 @@ object Dependencies {
3538

3639
val datastaxJavaDriverCore = "4.3.1"
3740
val doobie = "0.7.1"
41+
val grpc = "1.25.0"
3842
val http4s = "0.20.15"
3943
val micrometerCore = "1.3.2"
4044
val micrometerJmx = "1.3.2"

0 commit comments

Comments
 (0)