package models; import akka.actor.ActorRef; import akka.actor.Props; import akka.util.Timeout; import play.libs.Akka; import play.libs.F; import scala.concurrent.Future; import scala.concurrent.duration.Duration; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import static akka.pattern.Patterns.ask; /* In-memory publish/subscribe system */ public class AuctionRooms { final ActorRef ref = Akka.system().actorOf(Props.create(AuctionRoomsActor.class)); final Timeout t = new Timeout(Duration.create(1, TimeUnit.SECONDS)); /** * Subscribe to bid notifications for a given item * @param id Item id * @param subscriber Notification callback * @return A pair containing the current bids and a Subscription object (for un-subscribing) */ public F.Promise<F.Tuple<List<Bid>, Subscription>> subscribe(Long id, Consumer<Bid> subscriber) { return F.Promise.wrap((Future)ask(ref, new AuctionRoomsActor.Subscribe(id, subscriber), t)); } /** * Bid for an item * @param id Item id * @param name User name * @param price Bid price */ public void bid(Long id, String name, Double price) { ref.tell(new AuctionRoomsActor.ItemBid(id, name, price), null); } public static class Subscription { private final Long id; private final Consumer<Bid> subscriber; private final ActorRef ref; public Subscription(ActorRef ref, Long id, Consumer<Bid> subscriber) { this.ref = ref; this.id = id; this.subscriber = subscriber; } /** * Tell the subscription system that this subscription is not anymore interested in receiving notifications */ public void cancel() { ref.tell(new AuctionRoomsActor.Unsubscribe(id, subscriber), null); } } public static class Bid { public String name; public Double price; public Bid() {} public Bid(String name, Double price) { this.name = name; this.price = price; } } }