Skip to content

Commit

Permalink
Use Shared handlers simplifying a bit the demo
Browse files Browse the repository at this point in the history
Signed-off-by: slinkydeveloper <[email protected]>
  • Loading branch information
slinkydeveloper committed May 16, 2024
1 parent 2c90484 commit 933633d
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 235 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import dev.restate.sdk.http.vertx.RestateHttpEndpointBuilder
fun main() {
RestateHttpEndpointBuilder.builder()
.bind(OrderWorkflow())
.bind(OrderStatusService())
.bind(DeliveryManager())
.bind(OrderETAService())
.bind(DriverDeliveryMatcher())
.bind(DriverDigitalTwin())
.bind(DriverMobileAppSimulator()) // external mobile app on driver's phone
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
package dev.restate.sdk.examples

import dev.restate.sdk.annotation.Handler
import dev.restate.sdk.annotation.Shared
import dev.restate.sdk.annotation.VirtualObject
import dev.restate.sdk.common.TerminalException
import dev.restate.sdk.kotlin.KtStateKey
import dev.restate.sdk.kotlin.ObjectContext
import dev.restate.sdk.kotlin.SharedObjectContext

/**
* Digital twin for the driver. Represents a driver and his status, assigned delivery, and location.
Expand Down Expand Up @@ -66,9 +68,15 @@ class DriverDigitalTwin {
request.restaurantLocation,
request.customerLocation))

// Initialize the ETA service
OrderETAServiceClient.fromContext(ctx, request.orderId)
.send()
.notifyDeliveryLocations(
DeliveryLocations(request.restaurantLocation, request.customerLocation))

// Notify current location to the delivery service
ctx.get(DRIVER_LOCATION)?.let {
DeliveryManagerClient.fromContext(ctx, request.orderId).send().handleDriverLocationUpdate(it)
OrderETAServiceClient.fromContext(ctx, request.orderId).send().notifyDriverLocationUpdate(it)
}
}

Expand All @@ -88,7 +96,8 @@ class DriverDigitalTwin {
ctx.set(ASSIGNED_DELIVERY, currentDelivery)

// Update the status of the delivery in the delivery manager
DeliveryManagerClient.fromContext(ctx, currentDelivery.orderId).send().notifyDeliveryPickup()
OrderWorkflowClient.fromContext(ctx, currentDelivery.orderId).send().notifyDeliveryPickup()
OrderETAServiceClient.fromContext(ctx, currentDelivery.orderId).send().notifyDeliveryPickup()
}

/** Gets called by the driver's mobile app when he has delivered the order to the customer. */
Expand All @@ -105,9 +114,7 @@ class DriverDigitalTwin {
ctx.clear(ASSIGNED_DELIVERY)

// Notify the delivery service that the delivery was delivered
DeliveryManagerClient.fromContext(ctx, assignedDelivery.orderId)
.send()
.notifyDeliveryDelivered()
OrderWorkflowClient.fromContext(ctx, assignedDelivery.orderId).send().notifyDeliveryDelivered()

// Update the status of the driver to idle
ctx.set(DRIVER_STATUS, DriverStatus.IDLE)
Expand All @@ -121,7 +128,7 @@ class DriverDigitalTwin {

// Update the location of the delivery, if there is one
ctx.get(ASSIGNED_DELIVERY)?.let {
DeliveryManagerClient.fromContext(ctx, it.orderId).send().handleDriverLocationUpdate(location)
OrderETAServiceClient.fromContext(ctx, it.orderId).send().notifyDriverLocationUpdate(location)
}
}

Expand All @@ -130,8 +137,8 @@ class DriverDigitalTwin {
* assigned. Gets polled by the driver's mobile app at regular intervals to check if a delivery
* got assigned to him.
*/
@Handler
suspend fun getAssignedDelivery(ctx: ObjectContext): GetAssignedDeliveryResult {
@Shared
suspend fun getAssignedDelivery(ctx: SharedObjectContext): GetAssignedDeliveryResult {
return GetAssignedDeliveryResult(ctx.get(ASSIGNED_DELIVERY))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (c) 2024 - Restate Software, Inc., Restate GmbH
*
* This file is part of the Restate examples,
* which is released under the MIT license.
*
* You can find a copy of the license in the file LICENSE
* in the root directory of this repository or package or at
* https://github.com/restatedev/examples/
*/
package dev.restate.sdk.examples

import dev.restate.sdk.annotation.Handler
import dev.restate.sdk.annotation.Shared
import dev.restate.sdk.annotation.VirtualObject
import dev.restate.sdk.common.TerminalException
import dev.restate.sdk.examples.utils.GeoUtils
import dev.restate.sdk.kotlin.KtStateKey
import dev.restate.sdk.kotlin.ObjectContext
import dev.restate.sdk.kotlin.SharedObjectContext

/** Virtual object tracking the ETA, keyed by order-id */
@VirtualObject
class OrderETAService {
companion object {
private val ORDER_ETA = KtStateKey.json<Long>("order-eta")
private val DELIVERY_LOCATIONS = KtStateKey.json<DeliveryLocations>("delivery-locations")
private val DELIVERY_IS_PICKED_UP = KtStateKey.json<Unit>("order-is-picked-up")
}

/** Gets called by the webUI frontend to display the status of an order. */
@Shared
suspend fun get(ctx: SharedObjectContext): Long {
return ctx.get(ORDER_ETA) ?: -1L
}

@Handler
suspend fun notifyDeliveryLocations(ctx: ObjectContext, locations: DeliveryLocations) {
ctx.set(DELIVERY_LOCATIONS, locations)
}

/**
* Updates the location of the order. Gets called by
* DriverService.HandleDriverLocationUpdateEvent() (digital twin of the driver) when the driver
* has moved to a new location.
*/
@Handler
suspend fun notifyDeliveryPickup(ctx: ObjectContext) {
ctx.set(DELIVERY_IS_PICKED_UP, Unit)
}

/**
* Updates the location of the order. Gets called by
* DriverService.HandleDriverLocationUpdateEvent() (digital twin of the driver) when the driver
* has moved to a new location.
*/
@Handler
suspend fun notifyDriverLocationUpdate(ctx: ObjectContext, newLocation: Location) {
// Retrieve the delivery information for this delivery
val locations =
ctx.get(DELIVERY_LOCATIONS)
?: throw TerminalException(
"Driver is doing a delivery but there is no ongoing delivery.")

val isOrderPickedUp = ctx.get(DELIVERY_IS_PICKED_UP) != null

// Parse the new location, and calculate the ETA of the delivery to the customer
val eta =
if (isOrderPickedUp) GeoUtils.calculateEtaMillis(newLocation, locations.customer)
else
(GeoUtils.calculateEtaMillis(newLocation, locations.restaurant) +
GeoUtils.calculateEtaMillis(locations.restaurant, locations.customer))

// Update the ETA of the order
ctx.set(ORDER_ETA, eta)
}
}

This file was deleted.

Loading

0 comments on commit 933633d

Please sign in to comment.