nl_tokens: apply the given pending change to the backend using the dataHandlers
pl_tokens: function applyPendingChange ( pendingChange , tries , callback ) { var datasetId = pendingChange . datasetId ; if ( ! datasetId || ! pendingChange . action || ! pendingChange . uid || ! pendingChange . cuid || ! pendingChange . hash ) { debugError ( "[%s] invalid pendingChange request dropped :: item = %j" , datasetId , pendingChange ) ; return callback ( ) ; } debug ( '[%s] processPending :: item = %j' , datasetId , pendingChange ) ; if ( tries > retryLimit ) { //the pendingChange has been processed before. Mark it as failed debugError ( '[%s] processPending failed :: tries = %d  :: item = %j' , datasetId , tries , pendingChange ) ; return saveUpdate ( datasetId , pendingChange , SYNC_UPDATE_TYPES . FAILED , "crashed" , callback ) ; } pendingChange . tries = tries ; var action = pendingChange . action . toLowerCase ( ) ; var timer = metrics . startTimer ( ) ; function onComplete ( err ) { metricsClient . gauge ( metrics . KEYS . PENDING_CHANGE_PROCESS_TIME , { success : ! err , action : action } , timer . stop ( ) ) ; return <mask> ( err ) ; } switch ( action ) { case "create" : doCreate ( datasetId , pendingChange , onComplete ) ; break ; case "update" : doUpdate ( datasetId , pendingChange , onComplete ) ; break ; case "delete" : doDelete ( datasetId , pendingChange , onComplete ) ; break ; default : debugError ( "[%s] invalid pendingChange request dropped :: item = %j" , datasetId , pendingChange ) ; return onComplete ( ) ; } }