Resolving CUD conflicts === Rhoconnect CUD queue and potential conflicts --- By design, your Rhoconnect application supports parallel dispatching of the multiple client's requests via the asynchronous Resque jobs. This scenario can lead to a situation where two or more clients will try to perform CUD operations at the same time, potentially creating the race condition. For example, this can happen when two users will try to insert or delete the same record simultaneously. To handle this situation , Rhoconnect uses the CUD queue, which is being dispatched continuously. You can inspect this queue before the CUD operation is called and mark the conflicting records for special processing. To do this, you need to override the Source Adapter `validate` method that is called before the CUD queue is dispatched. This method has the following parameters:
String operation CUD operation marker, one of three: create, update, or delete
Array Of Record Hashes cud_queue CUD queue consisting of CUD request hashes, ordered from oldest to newest. Each entry in the queue contains a hash of CUD records to process. (Each CUD client request can contain more than one record
Array Of Client Ids client_queue This array is used to map the CUD request in the above queue to a corresponding client ID. i.e. CUD_queue[N] request was issued by client_queue[N] client. Please note that there may be several entries from the same client - if they came separately in time
Below you can see the example of the `validate` method parameters indicating two create requests containing the conflicting records: :::ruby client_1 = 'cid_1' cud_request_1 = { 'temp_cid1_1' => {'name' => 'iPhone'}, 'temp_cid1_2' => {'name' => 'Android'}} client_2 = 'cid_2' cud_request_2 = { 'temp_cid2_1' => {'name' => 'iPhone'}} # this record seems to be the duplicate of the record 'temp_cid1_1' operation = 'create' cud_queue = [ cud_request_1, cud_request_2 ] client_ids = [ client_1, client_2 ] Detecting the conflict and forcing an error --- Using the above `validate` method you can iterate through the queue and detect CUD conflicts based on the desired application logic. Once the conflicting record is found (for example, duplicate create request), you need to mark it by inserting the conflicting record parameters into the special hash structure that is returned by the `validate` method: :::ruby def validate(operation, cud_queue, client_ids) resulting_meta_hash = {} # iterating through the queue cud_queue.each_with_index do |cud_request, index| cud_request_client = client_ids[index] # iterating through the request records cud_request.each do |record_id, record_hash| # ... detecting the conflict here .... # !!! found a conflict - force an error error_record_id = record_id record_meta_data = { error_record_id => { :error => 'my_error_string: conflict is detected!!!' }} resulting_meta_hash[index] ||= {} resulting_meta_hash[index].merge!(record_meta_data) end end resulting_meta_hash end Once the `validate` method returns non-empty validation metadata hash structure, it will be used in processing the CUD queue. All marked records will not be processed, but instead an error will be sent back to the originating client with the user-provided error message.