/// <summary> /// Hanlde cluster-wide Remove(key) requests. /// </summary> /// <param name="info">the object containing parameters for this operation.</param> /// <returns>object to be sent back to the requestor.</returns> /// <remarks> /// Removes an item locally; however without generating notifications. /// <para> /// <b>Note:</b> When a client invokes <see cref="handleRemove"/>; it is the clients reponsibility /// to actaully initiate the notification. /// </para> /// </remarks> private object handleRemove(Address src, object info) { try { object result = null; if (info is object[]) { object[] args = info as Object[]; CallbackEntry cbEntry = null; OperationContext operationContext = null; if (args.Length > 3) cbEntry = args[3] as CallbackEntry; if (args.Length > 6) operationContext = args[6] as OperationContext; else if (args.Length > 4) operationContext = args[4] as OperationContext; else if (args.Length > 2) operationContext = args[2] as OperationContext; if (args != null && args.Length > 0) { object tmp = args[0]; if (tmp is Object[]) { result = Local_Remove((object[])tmp, ItemRemoveReason.Removed, src, cbEntry, true, operationContext); } else { object lockId = args[4]; LockAccessType accessType = (LockAccessType)args[5]; CacheEntry entry = Local_Remove(tmp, ItemRemoveReason.Removed, src, cbEntry, true, lockId, accessType, operationContext); /* send value and entry seperaty*/ OperationResponse opRes = new OperationResponse(); if (entry != null) { opRes.UserPayload = (entry.Value is CallbackEntry ? ((CallbackEntry)entry.Value).UserData : entry.UserData); opRes.SerializablePayload = entry.CloneWithoutValue(); } result = opRes; } } } /// Only the coordinator returns the object, this saves a lot of traffic because /// only one reply actually contains the object other replies are simply dummy objects. if (Cluster.IsCoordinator) return result; } catch (Exception) { if (_clusteredExceptions) throw; } return null; }
/// <summary> /// Hanlde cluster-wide Get(key) requests. /// </summary> /// <param name="info">the object containing parameters for this operation.</param> /// <returns>object to be sent back to the requestor.</returns> private object handleGet(object info) { try { object[] objs = info as object[]; OperationContext operationContext = null; bool isUserOperation = true; if (objs.Length > 1) operationContext = objs[1] as OperationContext; if (objs.Length > 2) isUserOperation = (bool)objs[2]; if (objs[0] is object[]) return Local_Get((object[])objs[0], operationContext); else { CacheEntry entry = Local_Get(objs[0],isUserOperation, operationContext); /* send value and entry seperaty*/ OperationResponse opRes = new OperationResponse(); if (entry != null) { UserBinaryObject ubObject = (UserBinaryObject)(entry.Value is CallbackEntry ? ((CallbackEntry)entry.Value).Value : entry.Value); opRes.UserPayload = ubObject.Data; opRes.SerializablePayload = entry.CloneWithoutValue(); } return opRes; } } catch (Exception) { if (_clusteredExceptions) throw; } return null; }
/// <summary> /// Adds a pair of key and value to the cache. If the specified key already exists /// in the cache; it is updated, otherwise a new item is added to the cache. /// </summary> /// <param name="info">the object containing parameters for this operation.</param> /// <returns>object to be sent back to the requestor.</returns> private object handleInsert(Address src, object info, Array userPayload) { try { object[] objs = (object[])info; bool returnEntry = false; OperationContext operationContext = null; //KS: operation Context if (objs.Length == 3) { operationContext = objs[2] as OperationContext; } //muds: //if client node is requesting for the previous cache entry //then cluster coordinator must send it back... if (objs.Length == 6) { returnEntry = (bool)objs[2] && Cluster.IsCoordinator; operationContext = objs[5] as OperationContext; } if (objs[0] is object[]) { object[] keys = (object[])objs[0]; CacheEntry[] entries = objs[1] as CacheEntry[]; return Local_Insert(keys, entries, src, true, operationContext); } else { object key = objs[0]; CacheEntry e = objs[1] as CacheEntry; e.Value = userPayload; object lockId = null; LockAccessType accessType = LockAccessType.IGNORE_LOCK; if (objs.Length == 6) { lockId = objs[3]; accessType = (LockAccessType)objs[4]; } CacheInsResultWithEntry resultWithEntry = Local_Insert(key, e, src, true, lockId, accessType, operationContext); /* send value and entry seperately*/ OperationResponse opRes = new OperationResponse(); if (resultWithEntry.Entry != null) { if (resultWithEntry.Entry.Value is CallbackEntry) { opRes.UserPayload = null; } else { //muds: //we need not to send this entry back... it is needed only for custom notifications and/or key dependencies... opRes.UserPayload = null; } if (returnEntry) resultWithEntry.Entry = resultWithEntry.Entry.CloneWithoutValue() as CacheEntry; else resultWithEntry.Entry = null; } opRes.SerializablePayload = resultWithEntry; return opRes; } } catch (Exception e) { if (_clusteredExceptions) throw; } return CacheInsResult.Failure; }
private OperationResponse handleTransferBucket(Address sender, object info) { object[] pack = info as object[]; ArrayList bucketIds = pack[0] as ArrayList; byte transferType = (byte) pack[1]; bool sparsedBuckets = (bool) pack[2]; int expectedTxfrId = (int) pack[3]; bool isBalanceDataLoad = (bool) pack[4]; if (_corresponders == null) _corresponders = new Hashtable(); StateTxfrCorresponder corresponder = null; lock (_corresponders.SyncRoot) { corresponder = _corresponders[sender] as StateTxfrCorresponder; if (corresponder == null) { corresponder = new StateTxfrCorresponder(this, _distributionMgr, sender, transferType); _corresponders[sender] = corresponder; } } corresponder.IsBalanceDataLoad = isBalanceDataLoad; //ask the corresponder to transfer data for the bucket(s). Alachisoft.NCache.Caching.Topologies.Clustered.StateTxfrInfo transferInfo = corresponder.TransferBucket(bucketIds, sparsedBuckets, expectedTxfrId); OperationResponse rsp = new OperationResponse(); rsp.SerializablePayload = transferInfo; rsp.SerilizationStream = transferInfo.SerlizationStream; //if (transferInfo.PayLoad != null) // rsp.UserPayload = transferInfo.PayLoad; return rsp; }
/// <summary> /// Hanlde cluster-wide Remove(key) requests. /// </summary> /// <param name="info">the object containing parameters for this operation.</param> /// <returns>object to be sent back to the requestor.</returns> /// <remarks> /// This method triggers <see cref="OnItemsRemoved"/>, which then triggers a cluster-wide /// Item removed notification. /// </remarks> private object handleRemove(Address src, object info) { try { object[] param = (object[]) info; CallbackEntry cbEntry = null; OperationContext oc = null; if (param.Length > 3) cbEntry = param[3] as CallbackEntry; if (param.Length == 2) oc = param[1] as OperationContext; if (param.Length == 7) oc = param[6] as OperationContext; if (param.Length == 5) oc = param[4] as OperationContext; if (param[0] is object[]) { Hashtable table = Local_Remove((object[])param[0], (ItemRemoveReason)param[1], src, cbEntry, (bool)param[2], oc); return table; } else { object lockId = param[4]; LockAccessType accessType = (LockAccessType)param[5]; CacheEntry e = Local_Remove(param[0], (ItemRemoveReason)param[1], src, cbEntry, (bool)param[2], lockId, accessType, oc); OperationResponse opRes = new OperationResponse(); if (e != null) { UserBinaryObject ubObject = (UserBinaryObject) (e.Value is CallbackEntry ? ((CallbackEntry) e.Value).Value : e.Value); opRes.UserPayload = ubObject.Data; opRes.SerializablePayload = e.CloneWithoutValue(); } return opRes; } } catch (Exception) { if (_clusteredExceptions) throw; } return null; }
/// <summary> /// Adds a pair of key and value to the cache. If the specified key already exists /// in the cache; it is updated, otherwise a new item is added to the cache. /// </summary> /// <param name="info">the object containing parameters for this operation.</param> /// <returns>object to be sent back to the requestor.</returns> /// <remarks> /// This method triggers either <see cref="OnItemAdded"/> or <see cref="OnItemUpdated"/>, which /// in turn trigger either an item-added or item-updated cluster-wide notification. /// </remarks> private object handleInsert(Address src, object info, Array userPayload) { try { OperationContext operationContext = null; object[] objs = (object[]) info; if (objs.Length == 3) { operationContext = objs[2] as OperationContext; } else if (objs.Length == 5) { operationContext = objs[4] as OperationContext; } if (objs[0] is object[]) { object[] keyArr = (object[])objs[0]; CacheEntry[] valArr = (CacheEntry[])objs[1]; return Local_Insert(keyArr, valArr, src, true, operationContext); } else { object key = objs[0]; CacheEntry e = objs[1] as CacheEntry; e.Value = userPayload; object lockId = objs[2]; LockAccessType accessType = (LockAccessType) objs[3]; CacheInsResultWithEntry retVal = Local_Insert(key, e, src, true, lockId, accessType, operationContext); /* send value and entry seperaty*/ OperationResponse opRes = new OperationResponse(); if (retVal.Entry != null) { opRes.UserPayload = null; retVal.Entry = null; } opRes.SerializablePayload = retVal; return opRes; } } catch (Exception) { if (_clusteredExceptions) throw; } return null; }
/// <summary> /// Hanlde cluster-wide Get(key) requests. /// </summary> /// <param name="info">the object containing parameters for this operation.</param> /// <returns>object to be sent back to the requestor.</returns> private object handleGet(object info) { try { object[] args = info as object[]; if (args[0] is object[]) { Hashtable table = Local_Get((object[]) args[0], args[1] as OperationContext); return table; } else { object key = args[0]; object lockId = args[1]; DateTime lockDate = (DateTime) args[2]; LockAccessType accessType = (LockAccessType) args[3]; LockExpiration lockExpiration = (LockExpiration) args[4]; OperationContext operationContext = args[5] as OperationContext; CacheEntry entry = Local_Get(key, ref lockId, ref lockDate, lockExpiration, accessType, operationContext); OperationResponse opRes = new OperationResponse(); object[] response = new object[4]; if (entry != null) { UserBinaryObject ubObject = (UserBinaryObject) (entry.Value is CallbackEntry ? ((CallbackEntry) entry.Value).Value : entry.Value); opRes.UserPayload = ubObject.Data; response[0] = entry.CloneWithoutValue(); } response[1] = lockId; response[2] = lockDate; opRes.SerializablePayload = response; return opRes; } } catch (Exception) { if (_clusteredExceptions) throw; } return null; }
/* ---------------------- Interface RspCollector -------------------------- */ /// <summary> <b>Callback</b> (called by RequestCorrelator or Transport). /// Adds a response to the response table. When all responses have been received, /// <code>execute()</code> returns. /// </summary> public virtual void receiveResponse(Message m) { Address sender = m.Src, mbr; object val = null; if (_done) { NCacheLog.Warn("GroupRequest.receiveResponse()", "command is done; cannot add response !"); return; } if (suspects != null && suspects.Count > 0 && suspects.Contains(sender)) { NCacheLog.Warn("GroupRequest.receiveResponse()", "received response from suspected member " + sender + "; discarding"); return; } if (m.Length > 0) { try { if (m.responseExpected) { OperationResponse opRes = new OperationResponse(); opRes.SerializablePayload = m.getFlatObject(); opRes.UserPayload = m.Payload; val = opRes; } else { val = m.getFlatObject(); } } catch (System.Exception e) { NCacheLog.Error("GroupRequest.receiveResponse()", "exception=" + e.Message); } } lock (rsp_mutex) { bool isMainMember = false; for (int i = 0; i < membership.Length; i++) { mbr = membership[i]; if (mbr.Equals(sender)) { isMainMember = true; if (received[i] == NOT_RECEIVED) { responses[i] = val; received[i] = RECEIVED; if (NCacheLog.IsInfoEnabled) NCacheLog.Info("GroupRequest.receiveResponse()", "received response for request " + req_id + ", sender=" + sender + ", val=" + val); System.Threading.Monitor.PulseAll(rsp_mutex); // wakes up execute() break; } } } if (!isMainMember) { receivedFromNHops[sender] = RECEIVED; System.Threading.Monitor.PulseAll(rsp_mutex); } } }