예제 #1
0
void Journallable::apply_restored(const Operation &op)
{
   TRACEPX(PCOMN_Journal, DBGL_MIDLEV, "Applying restored " << op << " to " << *this) ;

   NOXCHECK(state() == ST_RESTORING) ;
   NOXCHECK(is_op_compatible(op)) ;

   try {
      // Needn't lock, needn't store
      op.apply(*this) ;

      atomic_op::preinc(&_changecnt) ;
   }
   catch (const std::runtime_error &x)
   {
      // We may choose to ignore an exception: when an operation is being stored into
      // the journal, it is written _before_ applying; so, although do_lock_target
      // (which is called _before_ storing the operation) can check whether the
      // operation is applicable, such check may be noncomprehensive, e.g. due to
      // performance/locking issues. As a result, the operation may fail after having
      // been saved (though leaving the Journallable in consistent state).
      // Such operation will also inevitably fail while being restored but failure may
      // (and should!) be ignored.
      if (!op.is_ignorable_exception(x))
      {
         LOGPXERR(PCOMN_Journal, "Non-ignorable exception restoring " << op
                   << " to " << *this << ": " << STDEXCEPTOUT(x)) ;
         throw ;
      }
      LOGINFO("Ignorable exception restoring " << op << " to " << *this << ": " << STDEXCEPTOUT(x)) ;
   }

   TRACEPX(PCOMN_Journal, DBGL_MIDLEV, "OK applied restored " << op) ;
}
예제 #2
0
	void apply(int number, char op) {
		Operation newOperation(number, op);

		int i = opStack.size() - 1;
		while (i >= 0) {
			Operation next = opStack[i--];
			if (Operators::rank(next.op) >= Operators::rank(op)) {
				newOperation.number = next.apply(newOperation.number);
				opStack.pop_back();
			} else {
				break;
			}
		}

		opStack.push_back(newOperation);
	}
예제 #3
0
void Journallable::apply_created(const Operation &op)
{
   TRACEPX(PCOMN_Journal, DBGL_MIDLEV, "Applying new " << op << " to " << *this) ;

   NOXCHECK((pcomn::one_of<ST_RESTORED, ST_ACTIVE, ST_CHECKPOINT>::is(state()))) ;
   NOXCHECK(is_op_compatible(op)) ;

   op.lock_target(*this, true) ;

   try {
      if (state() != ST_RESTORED)
      {
         TRACEPX(PCOMN_Journal, DBGL_LOWLEV, "Storing " << op << " to " << *unlocked_journal()) ;

         unlocked_journal()->store_operation(op) ;
      }
      TRACEPX(PCOMN_Journal, DBGL_VERBOSE, "Actually applying " << op) ;

      op.apply(*this) ;

      atomic_op::preinc(&_changecnt) ;
   }
   catch (const std::exception &x) {
      LOGPXERR_CALL(PCOMN_FAIL, PCOMN_Journal, STDEXCEPTOUT(x) << "\nwhile applying " << op
                    << "\nto " << *unlocked_journal() << ".\nThe operation is NOT applied") ;
      return ;
   }
   catch (...) {
      LOGPXERR_CALL(PCOMN_FAIL, PCOMN_Journal, "Unknown exception while applying " << op
                    << "\nto " << *unlocked_journal() << ".\nThe operation is NOT applied") ;
      return ;
   }

   op.lock_target(*this, false) ;

   TRACEPX(PCOMN_Journal, DBGL_MIDLEV, "OK applied new " << op) ;
}