add drill08

This commit is contained in:
Raffaele Mignone 2020-04-25 18:49:06 +02:00
parent 2cd3dd6549
commit bca1b43fa4
Signed by: norangebit
GPG Key ID: F5255658CB220573
18 changed files with 286 additions and 1 deletions

View File

@ -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")
} }

View File

@ -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

View 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!")}")
}

View 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
}
}

View File

@ -0,0 +1,10 @@
package drills.drill08.exercise1
import util.jms.replicatedobject.ReplicatedObject
fun main() {
val finder: Finder = FakeFinder()
ReplicatedObject(finder, "finder")
.start()
}

View 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")
}

View 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
}
}

View 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()
}

View 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
}
}

View 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")
}

View File

@ -0,0 +1,9 @@
package drills.drill08.exercise3
import drills.drill08.exercise2.FakeFinder
import util.jms.replicatedobject.ReplicatedObject
fun main() {
ReplicatedObject(FakeFinder(), "finder")
.start()
}

View 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)
}
}

View 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)
}
}

View 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);
}

View 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)
}
}

View File

@ -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()
}
}

View File

@ -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
}
}

View File

@ -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`
}
}