add drill08
This commit is contained in:
parent
2cd3dd6549
commit
bca1b43fa4
@ -21,6 +21,8 @@ dependencies {
|
|||||||
implementation(kotlin("stdlib-jdk8"))
|
implementation(kotlin("stdlib-jdk8"))
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.5")
|
||||||
implementation("org.apache.activemq:activemq-client:5.15.12")
|
implementation("org.apache.activemq:activemq-client:5.15.12")
|
||||||
|
implementation("org.glassfish.jersey.containers:jersey-container-grizzly2-http:2.25")
|
||||||
|
implementation("org.glassfish.jersey.media:jersey-media-json-jackson:2.25")
|
||||||
testCompile("junit", "junit", "4.12")
|
testCompile("junit", "junit", "4.12")
|
||||||
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.7.0-beta2")
|
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.7.0-beta2")
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ formatting:
|
|||||||
active: true
|
active: true
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
NoSemicolons:
|
NoSemicolons:
|
||||||
active: true
|
active: false
|
||||||
autoCorrect: true
|
autoCorrect: true
|
||||||
NoTrailingSpaces:
|
NoTrailingSpaces:
|
||||||
active: true
|
active: true
|
||||||
|
11
src/main/kotlin/drills/drill08/exercise1/Client.kt
Normal file
11
src/main/kotlin/drills/drill08/exercise1/Client.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package drills.drill08.exercise1
|
||||||
|
|
||||||
|
import util.jms.replicatedobject.ReplicatedObjectFactory
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val factory = ReplicatedObjectFactory(Finder::class.java)
|
||||||
|
val finder = factory.create("finder")
|
||||||
|
|
||||||
|
println("ciao: ${finder.find("ciao")}")
|
||||||
|
println("ciao!: ${finder.find("ciao!")}")
|
||||||
|
}
|
11
src/main/kotlin/drills/drill08/exercise1/Finder.kt
Normal file
11
src/main/kotlin/drills/drill08/exercise1/Finder.kt
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package drills.drill08.exercise1
|
||||||
|
|
||||||
|
interface Finder {
|
||||||
|
fun find(str: String): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeFinder : Finder {
|
||||||
|
override fun find(str: String): Boolean {
|
||||||
|
return str.length % 2 == 0
|
||||||
|
}
|
||||||
|
}
|
10
src/main/kotlin/drills/drill08/exercise1/Server.kt
Normal file
10
src/main/kotlin/drills/drill08/exercise1/Server.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package drills.drill08.exercise1
|
||||||
|
|
||||||
|
import util.jms.replicatedobject.ReplicatedObject
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val finder: Finder = FakeFinder()
|
||||||
|
|
||||||
|
ReplicatedObject(finder, "finder")
|
||||||
|
.start()
|
||||||
|
}
|
27
src/main/kotlin/drills/drill08/exercise2/Client.kt
Normal file
27
src/main/kotlin/drills/drill08/exercise2/Client.kt
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package drills.drill08.exercise2
|
||||||
|
|
||||||
|
import util.rmi.Client
|
||||||
|
import kotlin.time.ExperimentalTime
|
||||||
|
import kotlin.time.measureTime
|
||||||
|
|
||||||
|
@ExperimentalTime
|
||||||
|
fun main() {
|
||||||
|
Client(clientHandler).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalTime
|
||||||
|
val clientHandler = {
|
||||||
|
val finder = Client.lookup("finder") as Finder
|
||||||
|
|
||||||
|
val workerNumber = 4
|
||||||
|
|
||||||
|
val workers = Array(workerNumber) { Worker(finder) }
|
||||||
|
|
||||||
|
val elapsed = measureTime {
|
||||||
|
workers.forEach { it.start() }
|
||||||
|
workers.forEach { it.join() }
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Total elapsed time: $elapsed")
|
||||||
|
println("Throughput: ${(workerNumber * Worker.REQUEST_NUMBER) / elapsed.inSeconds} req/s")
|
||||||
|
}
|
18
src/main/kotlin/drills/drill08/exercise2/Finder.kt
Normal file
18
src/main/kotlin/drills/drill08/exercise2/Finder.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package drills.drill08.exercise2
|
||||||
|
|
||||||
|
import java.rmi.Remote
|
||||||
|
import java.rmi.RemoteException
|
||||||
|
import java.rmi.server.UnicastRemoteObject
|
||||||
|
|
||||||
|
interface Finder : Remote {
|
||||||
|
@Throws(RemoteException::class)
|
||||||
|
fun find(str: String): Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class FakeFinder : UnicastRemoteObject(), Finder {
|
||||||
|
override fun find(str: String): Boolean {
|
||||||
|
println(str)
|
||||||
|
for (i in 0 until 100000000L);
|
||||||
|
return str.length % 2 == 0
|
||||||
|
}
|
||||||
|
}
|
10
src/main/kotlin/drills/drill08/exercise2/Server.kt
Normal file
10
src/main/kotlin/drills/drill08/exercise2/Server.kt
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package drills.drill08.exercise2
|
||||||
|
|
||||||
|
import util.rmi.Server
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
Server {
|
||||||
|
val finder: Finder = FakeFinder()
|
||||||
|
Server.bind(finder, "finder")
|
||||||
|
}.start()
|
||||||
|
}
|
22
src/main/kotlin/drills/drill08/exercise2/Worker.kt
Normal file
22
src/main/kotlin/drills/drill08/exercise2/Worker.kt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package drills.drill08.exercise2
|
||||||
|
|
||||||
|
import kotlin.time.ExperimentalTime
|
||||||
|
import kotlin.time.measureTime
|
||||||
|
|
||||||
|
class Worker(private val finder: Finder) : Thread() {
|
||||||
|
@ExperimentalTime
|
||||||
|
override fun run() {
|
||||||
|
val elapsed = measureTime {
|
||||||
|
repeat(REQUEST_NUMBER) {
|
||||||
|
finder.find("test-$it")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Thread $this elapsed: $elapsed")
|
||||||
|
println("Thread $this mean time for request: ${elapsed / REQUEST_NUMBER}")
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val REQUEST_NUMBER = 60
|
||||||
|
}
|
||||||
|
}
|
29
src/main/kotlin/drills/drill08/exercise3/Client.kt
Normal file
29
src/main/kotlin/drills/drill08/exercise3/Client.kt
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package drills.drill08.exercise3
|
||||||
|
|
||||||
|
import drills.drill08.exercise2.Finder
|
||||||
|
import drills.drill08.exercise2.Worker
|
||||||
|
import util.rmi.Client
|
||||||
|
import kotlin.time.ExperimentalTime
|
||||||
|
import kotlin.time.measureTime
|
||||||
|
|
||||||
|
@ExperimentalTime
|
||||||
|
fun main() {
|
||||||
|
Client(clientHandler).start()
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalTime
|
||||||
|
val clientHandler = {
|
||||||
|
val finder = Client.lookup("finder") as Finder
|
||||||
|
|
||||||
|
val workerNumber = 4
|
||||||
|
|
||||||
|
val workers = Array(workerNumber) { Worker(finder) }
|
||||||
|
|
||||||
|
val elapsed = measureTime {
|
||||||
|
workers.forEach { it.start() }
|
||||||
|
workers.forEach { it.join() }
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Total elapsed time: $elapsed")
|
||||||
|
println("Throughput: ${(workerNumber * Worker.REQUEST_NUMBER) / elapsed.inSeconds} req/s")
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package drills.drill08.exercise3
|
||||||
|
|
||||||
|
import drills.drill08.exercise2.FakeFinder
|
||||||
|
import util.jms.replicatedobject.ReplicatedObject
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
ReplicatedObject(FakeFinder(), "finder")
|
||||||
|
.start()
|
||||||
|
}
|
21
src/main/kotlin/drills/drill08/exercise3/Server.kt
Normal file
21
src/main/kotlin/drills/drill08/exercise3/Server.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package drills.drill08.exercise3
|
||||||
|
|
||||||
|
import drills.drill08.exercise2.Finder
|
||||||
|
import util.jms.replicatedobject.ReplicatedObjectFactory
|
||||||
|
import util.rmi.Server
|
||||||
|
import java.rmi.server.UnicastRemoteObject
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
Server {
|
||||||
|
val finder = FinderProxy()
|
||||||
|
Server.bind(finder, "finder")
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
class FinderProxy : Finder, UnicastRemoteObject() {
|
||||||
|
private val finder = ReplicatedObjectFactory(Finder::class.java)
|
||||||
|
.create("finder")
|
||||||
|
override fun find(str: String): Boolean {
|
||||||
|
return finder.find(str)
|
||||||
|
}
|
||||||
|
}
|
22
src/main/kotlin/drills/drill08/exercise4/SearchService.kt
Normal file
22
src/main/kotlin/drills/drill08/exercise4/SearchService.kt
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package drills.drill08.exercise4
|
||||||
|
|
||||||
|
import drills.drill08.exercise2.Finder
|
||||||
|
import util.jms.replicatedobject.ReplicatedObjectFactory
|
||||||
|
import javax.ws.rs.Consumes
|
||||||
|
import javax.ws.rs.GET
|
||||||
|
import javax.ws.rs.Path
|
||||||
|
import javax.ws.rs.Produces
|
||||||
|
import javax.ws.rs.QueryParam
|
||||||
|
import javax.ws.rs.core.MediaType
|
||||||
|
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Path("/search")
|
||||||
|
class SearchService {
|
||||||
|
private val finder = ReplicatedObjectFactory(Finder::class.java).create("finder")
|
||||||
|
|
||||||
|
@GET
|
||||||
|
fun search(@QueryParam("str") str: String): Boolean {
|
||||||
|
return finder.find(str)
|
||||||
|
}
|
||||||
|
}
|
18
src/main/kotlin/drills/drill08/exercise4/Server.kt
Normal file
18
src/main/kotlin/drills/drill08/exercise4/Server.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package drills.drill08.exercise4
|
||||||
|
|
||||||
|
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory
|
||||||
|
import org.glassfish.jersey.server.ResourceConfig
|
||||||
|
import javax.ws.rs.core.UriBuilder
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
val uri = UriBuilder
|
||||||
|
.fromUri("http://localhost/rest")
|
||||||
|
.port(8484)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val resConfig = ResourceConfig().register(SearchService())
|
||||||
|
val server = GrizzlyHttpServerFactory.createHttpServer(uri, resConfig)
|
||||||
|
server.start()
|
||||||
|
|
||||||
|
while (server.isStarted);
|
||||||
|
}
|
17
src/main/kotlin/util/jms/replicatedobject/Call.kt
Normal file
17
src/main/kotlin/util/jms/replicatedobject/Call.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package util.jms.replicatedobject
|
||||||
|
|
||||||
|
import java.io.Serializable
|
||||||
|
|
||||||
|
data class Call(
|
||||||
|
val methodName: String,
|
||||||
|
val args: Array<out Any>
|
||||||
|
) : Serializable {
|
||||||
|
fun execOn(target: Any): Any {
|
||||||
|
val method = target::class.java.getMethod(
|
||||||
|
methodName,
|
||||||
|
*args.map { it::class.java }.toTypedArray()
|
||||||
|
)
|
||||||
|
|
||||||
|
return method.invoke(target, *args)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package util.jms.replicatedobject
|
||||||
|
|
||||||
|
import util.jms.replier.ActiveMQReplier
|
||||||
|
import java.io.Serializable
|
||||||
|
import javax.jms.ObjectMessage
|
||||||
|
|
||||||
|
class ReplicatedObject<T : Any>(
|
||||||
|
private val target: T,
|
||||||
|
queueName: String,
|
||||||
|
shared: Boolean = false
|
||||||
|
) {
|
||||||
|
private val replier = ActiveMQReplier(queueName, shared)
|
||||||
|
|
||||||
|
init {
|
||||||
|
replier.onRequest {
|
||||||
|
val call = (it as ObjectMessage).`object` as Call
|
||||||
|
replier.createObjectMessage(call.execOn(target) as Serializable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start() {
|
||||||
|
replier.start()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package util.jms.replicatedobject
|
||||||
|
|
||||||
|
import util.jms.requestor.ActiveMQRequestor
|
||||||
|
import java.lang.reflect.Proxy
|
||||||
|
|
||||||
|
class ReplicatedObjectFactory<T>(private val classType: Class<T>) {
|
||||||
|
fun create(queueName: String, shared: Boolean = false): T {
|
||||||
|
val requestor = ActiveMQRequestor(queueName, shared)
|
||||||
|
|
||||||
|
return Proxy.newProxyInstance(
|
||||||
|
this::class.java.classLoader,
|
||||||
|
arrayOf(classType),
|
||||||
|
ReplicatedObjectHandler(requestor)
|
||||||
|
) as T
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package util.jms.replicatedobject
|
||||||
|
|
||||||
|
import util.jms.requestor.Requestor
|
||||||
|
import java.lang.reflect.InvocationHandler
|
||||||
|
import java.lang.reflect.Method
|
||||||
|
import javax.jms.ObjectMessage
|
||||||
|
|
||||||
|
class ReplicatedObjectHandler(
|
||||||
|
private val requestor: Requestor
|
||||||
|
) : InvocationHandler {
|
||||||
|
override fun invoke(p0: Any, p1: Method, p2: Array<out Any>): Any {
|
||||||
|
val call = Call(p1.name, p2)
|
||||||
|
|
||||||
|
val msg = requestor.createObjectMessage(call)
|
||||||
|
|
||||||
|
return (requestor.request(msg) as ObjectMessage).`object`
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user