Concurrent booking system

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
0
down vote

favorite












I am trying to see how to create a booking system. Basically, I want to use "available" synchronizer utilities from util.concurrent and avoid using wait/notify/notifyAll to minimize the locking.



If you have a smarter idea, please suggest something. I want your review on:



  1. bookTicket


  2. cancelTicket methods

  3. Organization analysis

Here I created a manager class which actually does transactions for show and user, where one can isolate and "ask" show object to book it. I want to know what you think and why. I created manager instead of asking how to book a ticket. I think ticket-mgmt is a separate task that is no "Shows" responsibility.



import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class BookingMgr {

//Map<userId, List<Show>>
private Map<Integer, List<Show>> users;
//Map<showId, List<Users>>
private Map<Integer, List<User>> shows;

//show_id to totalSeats i.e Map<show_id, new Semaphore(300)>
private Map<Integer, Semaphore> showsSeats;

ReentrantReadWriteLock cancelLock = new ReentrantReadWriteLock();


public BookingMgr()
users = new ConcurrentHashMap<>();
shows = new ConcurrentHashMap<>();
showsSeats = new ConcurrentHashMap<>();


// I didn't snyc it since it is by show_id, so if someone adds the show at the same it the last one will win.. which is acceptable.
public void addShow(int showId, int seats)
showsSeats.compute(showId, (k, v) -> new Semaphore(seats));


public void removeShow(int showId)
throw new UnsupportedOperationException();


public boolean bookTicket(int userId, int showId, int numSeats) throws Exception
//handle to available seats
Semaphore availableSeats = showsSeats.get(showId);

//even if we were preempted, this call should still give correct available permits?
// so we should be still good.
try
boolean success = availableSeats.tryAcquire(numSeats, 10, TimeUnit.MILLISECONDS);
if (success)
//this are immutable users & shows, so even if we get pre-empted we are fine whenever we are back
//we can update this. // assume cacheAccess exists.
users.compute(userId, (k, v) -> new ArrayList<Show>().add(cache.getShow(showId)));
shows.compute(showId, (k, v) -> new ArrayList<Show>().add(cache.getUser(userId)));
return true;

catch (InterruptedException e)
e.printStackTrace();

throw new Exception("Availables tkts: " + availableSeats.availablePermits());


public boolean cancelTicket(int userId, int showId, int numSeats) throws Exception
//handle to available seats
Semaphore availableSeats = showsSeats.get(showId);

//even if we were preempted, this call should still give correct available permits?
// so we should be still good.
try
cancelLock.writeLock();
availableSeats.release(numSeats);
//this are immutable users & shows, so even if we get pre-empted we are fine whenever we are back
//we can update this. // assume cacheAccess exists.
List<Show> userShows = users.get(userId);
List<User> showUsers = shows.get(showId);
userShows.remove(showId);
showUsers.remove(userId);
return true;
catch (Exception e)
throw new Exception("Can't cancel - Availables tkts: " + availableSeats.availablePermits());
finally
cancelLock.writeLock().unlock();




public interface Show
int getShowId();
int getTotalSeats();


public interface User
int getId();







share|improve this question



























    up vote
    0
    down vote

    favorite












    I am trying to see how to create a booking system. Basically, I want to use "available" synchronizer utilities from util.concurrent and avoid using wait/notify/notifyAll to minimize the locking.



    If you have a smarter idea, please suggest something. I want your review on:



    1. bookTicket


    2. cancelTicket methods

    3. Organization analysis

    Here I created a manager class which actually does transactions for show and user, where one can isolate and "ask" show object to book it. I want to know what you think and why. I created manager instead of asking how to book a ticket. I think ticket-mgmt is a separate task that is no "Shows" responsibility.



    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.ReentrantReadWriteLock;

    public class BookingMgr {

    //Map<userId, List<Show>>
    private Map<Integer, List<Show>> users;
    //Map<showId, List<Users>>
    private Map<Integer, List<User>> shows;

    //show_id to totalSeats i.e Map<show_id, new Semaphore(300)>
    private Map<Integer, Semaphore> showsSeats;

    ReentrantReadWriteLock cancelLock = new ReentrantReadWriteLock();


    public BookingMgr()
    users = new ConcurrentHashMap<>();
    shows = new ConcurrentHashMap<>();
    showsSeats = new ConcurrentHashMap<>();


    // I didn't snyc it since it is by show_id, so if someone adds the show at the same it the last one will win.. which is acceptable.
    public void addShow(int showId, int seats)
    showsSeats.compute(showId, (k, v) -> new Semaphore(seats));


    public void removeShow(int showId)
    throw new UnsupportedOperationException();


    public boolean bookTicket(int userId, int showId, int numSeats) throws Exception
    //handle to available seats
    Semaphore availableSeats = showsSeats.get(showId);

    //even if we were preempted, this call should still give correct available permits?
    // so we should be still good.
    try
    boolean success = availableSeats.tryAcquire(numSeats, 10, TimeUnit.MILLISECONDS);
    if (success)
    //this are immutable users & shows, so even if we get pre-empted we are fine whenever we are back
    //we can update this. // assume cacheAccess exists.
    users.compute(userId, (k, v) -> new ArrayList<Show>().add(cache.getShow(showId)));
    shows.compute(showId, (k, v) -> new ArrayList<Show>().add(cache.getUser(userId)));
    return true;

    catch (InterruptedException e)
    e.printStackTrace();

    throw new Exception("Availables tkts: " + availableSeats.availablePermits());


    public boolean cancelTicket(int userId, int showId, int numSeats) throws Exception
    //handle to available seats
    Semaphore availableSeats = showsSeats.get(showId);

    //even if we were preempted, this call should still give correct available permits?
    // so we should be still good.
    try
    cancelLock.writeLock();
    availableSeats.release(numSeats);
    //this are immutable users & shows, so even if we get pre-empted we are fine whenever we are back
    //we can update this. // assume cacheAccess exists.
    List<Show> userShows = users.get(userId);
    List<User> showUsers = shows.get(showId);
    userShows.remove(showId);
    showUsers.remove(userId);
    return true;
    catch (Exception e)
    throw new Exception("Can't cancel - Availables tkts: " + availableSeats.availablePermits());
    finally
    cancelLock.writeLock().unlock();




    public interface Show
    int getShowId();
    int getTotalSeats();


    public interface User
    int getId();







    share|improve this question























      up vote
      0
      down vote

      favorite









      up vote
      0
      down vote

      favorite











      I am trying to see how to create a booking system. Basically, I want to use "available" synchronizer utilities from util.concurrent and avoid using wait/notify/notifyAll to minimize the locking.



      If you have a smarter idea, please suggest something. I want your review on:



      1. bookTicket


      2. cancelTicket methods

      3. Organization analysis

      Here I created a manager class which actually does transactions for show and user, where one can isolate and "ask" show object to book it. I want to know what you think and why. I created manager instead of asking how to book a ticket. I think ticket-mgmt is a separate task that is no "Shows" responsibility.



      import java.util.ArrayList;
      import java.util.List;
      import java.util.Map;
      import java.util.concurrent.ConcurrentHashMap;
      import java.util.concurrent.Semaphore;
      import java.util.concurrent.TimeUnit;
      import java.util.concurrent.locks.ReentrantReadWriteLock;

      public class BookingMgr {

      //Map<userId, List<Show>>
      private Map<Integer, List<Show>> users;
      //Map<showId, List<Users>>
      private Map<Integer, List<User>> shows;

      //show_id to totalSeats i.e Map<show_id, new Semaphore(300)>
      private Map<Integer, Semaphore> showsSeats;

      ReentrantReadWriteLock cancelLock = new ReentrantReadWriteLock();


      public BookingMgr()
      users = new ConcurrentHashMap<>();
      shows = new ConcurrentHashMap<>();
      showsSeats = new ConcurrentHashMap<>();


      // I didn't snyc it since it is by show_id, so if someone adds the show at the same it the last one will win.. which is acceptable.
      public void addShow(int showId, int seats)
      showsSeats.compute(showId, (k, v) -> new Semaphore(seats));


      public void removeShow(int showId)
      throw new UnsupportedOperationException();


      public boolean bookTicket(int userId, int showId, int numSeats) throws Exception
      //handle to available seats
      Semaphore availableSeats = showsSeats.get(showId);

      //even if we were preempted, this call should still give correct available permits?
      // so we should be still good.
      try
      boolean success = availableSeats.tryAcquire(numSeats, 10, TimeUnit.MILLISECONDS);
      if (success)
      //this are immutable users & shows, so even if we get pre-empted we are fine whenever we are back
      //we can update this. // assume cacheAccess exists.
      users.compute(userId, (k, v) -> new ArrayList<Show>().add(cache.getShow(showId)));
      shows.compute(showId, (k, v) -> new ArrayList<Show>().add(cache.getUser(userId)));
      return true;

      catch (InterruptedException e)
      e.printStackTrace();

      throw new Exception("Availables tkts: " + availableSeats.availablePermits());


      public boolean cancelTicket(int userId, int showId, int numSeats) throws Exception
      //handle to available seats
      Semaphore availableSeats = showsSeats.get(showId);

      //even if we were preempted, this call should still give correct available permits?
      // so we should be still good.
      try
      cancelLock.writeLock();
      availableSeats.release(numSeats);
      //this are immutable users & shows, so even if we get pre-empted we are fine whenever we are back
      //we can update this. // assume cacheAccess exists.
      List<Show> userShows = users.get(userId);
      List<User> showUsers = shows.get(showId);
      userShows.remove(showId);
      showUsers.remove(userId);
      return true;
      catch (Exception e)
      throw new Exception("Can't cancel - Availables tkts: " + availableSeats.availablePermits());
      finally
      cancelLock.writeLock().unlock();




      public interface Show
      int getShowId();
      int getTotalSeats();


      public interface User
      int getId();







      share|improve this question













      I am trying to see how to create a booking system. Basically, I want to use "available" synchronizer utilities from util.concurrent and avoid using wait/notify/notifyAll to minimize the locking.



      If you have a smarter idea, please suggest something. I want your review on:



      1. bookTicket


      2. cancelTicket methods

      3. Organization analysis

      Here I created a manager class which actually does transactions for show and user, where one can isolate and "ask" show object to book it. I want to know what you think and why. I created manager instead of asking how to book a ticket. I think ticket-mgmt is a separate task that is no "Shows" responsibility.



      import java.util.ArrayList;
      import java.util.List;
      import java.util.Map;
      import java.util.concurrent.ConcurrentHashMap;
      import java.util.concurrent.Semaphore;
      import java.util.concurrent.TimeUnit;
      import java.util.concurrent.locks.ReentrantReadWriteLock;

      public class BookingMgr {

      //Map<userId, List<Show>>
      private Map<Integer, List<Show>> users;
      //Map<showId, List<Users>>
      private Map<Integer, List<User>> shows;

      //show_id to totalSeats i.e Map<show_id, new Semaphore(300)>
      private Map<Integer, Semaphore> showsSeats;

      ReentrantReadWriteLock cancelLock = new ReentrantReadWriteLock();


      public BookingMgr()
      users = new ConcurrentHashMap<>();
      shows = new ConcurrentHashMap<>();
      showsSeats = new ConcurrentHashMap<>();


      // I didn't snyc it since it is by show_id, so if someone adds the show at the same it the last one will win.. which is acceptable.
      public void addShow(int showId, int seats)
      showsSeats.compute(showId, (k, v) -> new Semaphore(seats));


      public void removeShow(int showId)
      throw new UnsupportedOperationException();


      public boolean bookTicket(int userId, int showId, int numSeats) throws Exception
      //handle to available seats
      Semaphore availableSeats = showsSeats.get(showId);

      //even if we were preempted, this call should still give correct available permits?
      // so we should be still good.
      try
      boolean success = availableSeats.tryAcquire(numSeats, 10, TimeUnit.MILLISECONDS);
      if (success)
      //this are immutable users & shows, so even if we get pre-empted we are fine whenever we are back
      //we can update this. // assume cacheAccess exists.
      users.compute(userId, (k, v) -> new ArrayList<Show>().add(cache.getShow(showId)));
      shows.compute(showId, (k, v) -> new ArrayList<Show>().add(cache.getUser(userId)));
      return true;

      catch (InterruptedException e)
      e.printStackTrace();

      throw new Exception("Availables tkts: " + availableSeats.availablePermits());


      public boolean cancelTicket(int userId, int showId, int numSeats) throws Exception
      //handle to available seats
      Semaphore availableSeats = showsSeats.get(showId);

      //even if we were preempted, this call should still give correct available permits?
      // so we should be still good.
      try
      cancelLock.writeLock();
      availableSeats.release(numSeats);
      //this are immutable users & shows, so even if we get pre-empted we are fine whenever we are back
      //we can update this. // assume cacheAccess exists.
      List<Show> userShows = users.get(userId);
      List<User> showUsers = shows.get(showId);
      userShows.remove(showId);
      showUsers.remove(userId);
      return true;
      catch (Exception e)
      throw new Exception("Can't cancel - Availables tkts: " + availableSeats.availablePermits());
      finally
      cancelLock.writeLock().unlock();




      public interface Show
      int getShowId();
      int getTotalSeats();


      public interface User
      int getId();









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jun 4 at 3:11









      Jamal♦

      30.1k11114225




      30.1k11114225









      asked Jun 4 at 0:51









      sendi

      112




      112

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195780%2fconcurrent-booking-system%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f195780%2fconcurrent-booking-system%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation