Iulian dogariu the sad story of the server etc
-
Upload
codecampiasi -
Category
Technology
-
view
115 -
download
0
description
Transcript of Iulian dogariu the sad story of the server etc
The Sad ˝Story ˝
Of the Server ˝that Tries to ˝
Please Everyone
Iulian Dogariu CodeCamp 25 Oct 2014
Lil' serverobject Tickets extends Controller {
def book(eventId: Int, count: Int) = Action {
val bookings: Seq[Booking] =
TicketsRepository.bookForEvent(eventId, count)
Ok(s"Thank you! These are your bookings " +
bookings.mkString("\n"))
}
}
Lil' serverobject Tickets extends Controller {
def book(eventId: Int, count: Int) = Action {
val bookings: Seq[Booking] =
TicketsRepository.bookForEvent(eventId, count)
Ok(s"Thank you! These are your bookings " +
bookings.mkString("\n"))
}
}
More than a lil'def bookForEvent(eventId: Int, count: Int): Seq[Booking] = {
DB.withTransaction { implicit c =>
val numAvailableTickets: Int = SQL(
"SELECT num_free FROM tickets WHERE event_id={eventId}").
on("eventId" -> eventId).as(SqlParser.int("num_free").single)
(0 to count).map { _ =>
val bookingId: Option[Long] = SQL(
"INSERT INTO bookings(event_id)" +
" VALUES({eventId})").on('eventId -> eventId).executeInsert()
Booking(bookingId, eventId)
}
}
}
More than a lil'
How bad is it?
Normal CPU instruction
Fetch from RAM
Disk seek
Ping from Iași to Bucharest
Ping from Iași to USA
0.5 nsec
120 nsec
10 msec
30 msec
130 msec
No, really
Normal CPU instruction
Fetch from RAM
Disk seek
Ping from Iași to Bucharest
Ping from Iași to USA
1 sec
4 min
7.5 Months
2 Years
6 Years
Back to the lil' server
Back to the lil' server
Back to the lil' server
What does the user see?
If I only knew...
• I'd go somewhere else!
Show me the bottleneck
Queues and messages bookingActor ! NewBookingCommand(1, 2)
def receive = {
case BookingSucceeded(eventId, bookings) =>
println(s"Thank you!" + bookings.mkString("\n"))
}
class BookingActor extends Actor {
def receive = {
case NewBookingCommand(eventId, ct) =>
val bookings = TicketsRepository.bookForEvent(eventId, ct)
sender ! BookingSucceeded(eventId, bookings)
}
}
One small step
Pulling workGIMME WORK!!
WIP
The math of WIP
Push back
Push back
Reactive streams
Reactive streams
val bookingFlow =
Flow[NewBookingCommand].map { command =>
val bookings = TicketsRepository.
bookForEvent(command.eventId, command.count)
BookingSucceeded(
command.eventId, bookings)
}
val in = ThunkTap[NewBookingCommand] {
// Flood with requests
Some(NewBookingCommand(1, 2))
}
val out = ForeachDrain[BookingSucceeded] {
case BookingSucceeded(eventId, bookings) =>
println(s"Thank you!" + bookings.mkString("\n"))
}
FlowGraph { implicit b =>
in ~> bookingFlow ~> out
}.run()
Altogether nowFlowTap
Drain
Recap
• Do you really know what's slow in your code?
• Queues make bottlenecks obvious
• If you can't serve me, tell me so ("Agree to Start")
• Because people pleasers end up disappointing everyone equally :-)
The Soup Nazi problem
Q & A ?
Thank You, Come Again
And please fill in the evaluation form :-)