HermannHH
HermannHH

Reputation: 1772

Smart user process queuing using Rails 4

I have a few ideas regarding this one, but would like to gather some intel before implementing a solution.

I have an app where new records need to be manually assessed by customer service agents. Let's assume that I get 100 new customer queries and I have 10 Customer Agents that need to answer these queries. What is the best way to implement this queuing processor? Points to note:

  1. Only one agent can work on a request at any given time
  2. If another agent is already working on a record, another agent should not be able to access it.
  3. The system needs to be smart in the sense that it should be able to handle when multiple agents try to access the same record at the same time (I know the odds of users trying to access the same record at exactly the same time might be slim but I still need to accommodate for this)

Some of he solutions I've thought of:

  1. Locking a database record if an agent opens it (Does this solve #3 above?)
  2. Assigning records randomly to only one agent at a time

Does anybody have an idea of what the best solution might be? (Is there a gem that I can use for this sort of thing?)

Thanks.

Upvotes: 1

Views: 22

Answers (1)

smathy
smathy

Reputation: 27971

These are all fairly simple to solve. You'll have a Customer model which refers to the CustomerAgent who is assigned to process that customer, so you'll have a field of customer_agent_id in your Customer schema, this will initially be set to NULL.

You will create a scope on your Customer model like:

scope :available, -> { where customer_agent_id:nil }

...and when you're looking for the next available record for a Customer Agent to process you'll use that scope:

@next_customer = Customer.available.first

You will also use that scope when you update the record with the CustomerAgent association, like this (I'm assuming that the current_user helper is pointing to the currently logged in Customer Agent):

rows = Customer.available.where(id:@next_customer).update_all(customer_agent_id:current_user)
if rows == 1
  # assigned correctly to this agent
else
  # agent missed out, loop back and get another customer
end

Basically this will ensure that the SQL statement will end up something like this:

UPDATE customers SET customer_agent_id = 24 WHERE id = 5 AND customer_agent_id IS NULL;

As you can see, that SQL will fail at the DB level if some other agent has just been assigned that Customer (because the customer_agent_id won't be NULL anymore) and you'll get 0 returned.

Upvotes: 1

Related Questions