in src/ModernTacoShop/TrackOrder/src/Services/TrackOrderService.cs [76:159]
public override async Task GetOrderStatus(OrderId request, IServerStreamWriter<Order> responseStream, ServerCallContext serverCallContext)
{
try
{
if (string.IsNullOrEmpty(_tableName))
{
var systemsManagementClient = new AmazonSimpleSystemsManagementClient();
var tableNameParameter = await systemsManagementClient.GetParameterAsync(
new GetParameterRequest { Name = "/ModernTacoShop/TrackOrder/OrderTableName" });
_tableName = tableNameParameter.Parameter.Value;
}
var client = new AmazonDynamoDBClient();
var context = new DynamoDBContext(client);
var orderDynamoDbRecord = await context.LoadAsync<TrackOrderDynamoDbRecord>(request.Id,
new DynamoDBOperationConfig() { OverrideTableName = _tableName });
var order = orderDynamoDbRecord.ToOrder();
// Simulate an order being tracked. Update the position every few seconds.
var maximum = 30; // 60 seconds * 5 minutes
var i = 0;
var random = new Random();
while (!serverCallContext.CancellationToken.IsCancellationRequested && i <= maximum)
{
switch (i)
{
case var _ when i < 5:
order.Status = OrderStatus.Preparing;
break;
case var _ when i >= 5 && i < maximum:
order.Status = OrderStatus.InTransit;
if (order.LastPosition == null)
{
// We don't have a position. Initialize it with the coordinates of the restaurant.
order.LastPosition = new Point()
{
Latitude = _restaurantLatitude.ToString(),
Longitude = _restaurantLongitude.ToString()
};
}
else
{
// Simulate updates to the position with realistic-ish (but fake) motion.
var latitudeValue = Decimal.Parse(order.LastPosition.Latitude);
var longitudeValue = Decimal.Parse(order.LastPosition.Longitude);
var latitudeIncrement = new Decimal(random.Next(5, 20)) / 100000;
var longitudeIncrement = -1 * new Decimal(random.Next(5, 20)) / 100000;
order.LastPosition.Latitude = (latitudeValue + latitudeIncrement).ToString();
order.LastPosition.Longitude = (longitudeValue + longitudeIncrement).ToString();
}
break;
case var _ when i == maximum:
// The order has been delivered.
order.Status = OrderStatus.Delivered;
break;
default:
break;
}
var record = new TrackOrderDynamoDbRecord(order);
await context.SaveAsync(record, new DynamoDBOperationConfig() { OverrideTableName = _tableName });
await responseStream.WriteAsync(order);
// Pause before the next stream write.
await Task.Delay(5000);
i++;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in GetOrderStatus");
throw;
}
}