Ejemplo n.º 1
0
func (mut *mutation) executeObjectOperation(db *Db, replay bool) (err os.Error) {
	vs := db.viewstateManager.getViewState(mut.token, mut.vs)
	if vs == nil {
		log.Warning("Viewstate not found to execute object mutation: token=%d, vs=%d", mut.token, mut.vs)
		return os.NewError(fmt.Sprintf("Unknown ViewState to execute object operation on (token=%d, vs=%d)", mut.token, mut.vs))
	}

	container := mut.op.getContainer()
	key := mut.op.getKey()

	newObj := object{
		segment:  mut.seg.id,
		position: mut.segEntry.relativePosition(),
	}

	// unless we are replaying, we mutate the object
	if !replay {
		curObj, err := vs.getObject(container, key, true)
		if err != nil {
			return err
		}

		newObj.data = curObj.data // TODO: CLONE DATA!!
		err = mut.op.mutateObject(&newObj)
	}

	vs.setObject(container, key, newObj)
	return
}
Ejemplo n.º 2
0
func (comm *Comm) startMessageTracker() {
	// track messages
	for {
		if comm.running {
			for hash, msgTrack := range comm.messageTrackers {
				diff := int((time.Nanoseconds() - msgTrack.lastTime) / 1000000)

				// TODO: Use the right retry delay

				// check the acknowledgement
				if msgTrack.message.Timeout != 0 && diff >= msgTrack.message.Timeout {
					comm.trackersMutex.Lock()
					msgTrack, found := comm.messageTrackers[hash]

					// make sure the message tracker is still there
					// we may have received an ack while locking
					if found {
						msgTrack.retries++
						msgTrack.lastTime = time.Nanoseconds() + int64(msgTrack.message.RetryDelay*1000*1000)

						if msgTrack.retries > msgTrack.message.Retries {
							log.Warning("%d: Comm: Timeout for message %s after %d ms. Not retrying!\n", comm.Cluster.MyNode.Id, msgTrack.message, diff)

							// remove from acknowledgable messages list
							comm.messageTrackers[hash] = nil, false

							go func() {
								if msgTrack.message.OnTimeout != nil {
									msgTrack.message.OnTimeout(true)
								}

								if msgTrack.message.LastTimeoutAsError {
									msgTrack.message.OnError(msgTrack.message, ErrorTimeout)
								}

								msgTrack.message.Release()
							}()

						} else {
							go func() {
								retry := true
								handled := false
								if msgTrack.message.OnTimeout != nil {
									retry, handled = msgTrack.message.OnTimeout(false)
								}

								if retry && !handled {
									seekable, _ := msgTrack.message.DataIsSeekable()
									if msgTrack.message.Data != nil && !seekable {
										log.Error("%d: Comm: Cannot automatically retry message %s after %d ms because data is not seekable!", comm.Cluster.MyNode.Id, msgTrack.message, diff)
									} else {
										log.Warning("%d: Comm: Timeout for message %s after %d ms. Retrying %d of %d\n", comm.Cluster.MyNode.Id, msgTrack.message, diff, msgTrack.retries, msgTrack.message.Retries)

										comm.SendNode(msgTrack.destination, msgTrack.message)
									}
								}
							}()
						}
					}

					comm.trackersMutex.Unlock()

					// cleanup for OnError and OnResponse tracked messages
				} else if diff >= TRACKER_CLEAN_TIME {
					comm.trackersMutex.Lock()
					_, found := comm.messageTrackers[hash]

					// make sure the message is still there
					// we may have received an error or response
					// while waiting for the locking
					if found {
						comm.messageTrackers[hash] = nil, false
					}

					comm.trackersMutex.Unlock()
				}
			}
		}

		// sleep
		time.Sleep(TRACKER_LOOP_SLEEP * 1000 * 1000)
	}
}