text: /*
   * Copyright (C) 2018 Codership Oy <info@codership.com>
   *
   * This file is part of wsrep-lib.
   *
   * Wsrep-lib is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 2 of the License, or
   * (at your option) any later version.
   *
   * Wsrep-lib is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with wsrep-lib.  If not, see <https://www.gnu.org/licenses/>.
   */
  
  /** @file client_service.hpp
   *
   * This file will define a `callback` abstract interface for a
   * DBMS client session service. The interface will define methods
   * which will be called by the wsrep-lib.
   */
  
  #ifndef WSREP_CLIENT_SERVICE_HPP
  #define WSREP_CLIENT_SERVICE_HPP
  
  #include "buffer.hpp"
  #include "provider.hpp"
  #include "mutex.hpp"
  #include "lock.hpp"
  
  namespace wsrep
  {
      class client_service
      {
      public:
          client_service() { }
          virtual ~client_service() { }
  
          /**
           * Return true if the current transaction has been interrupted
           * by the DBMS. The lock which is passed to interrupted call
           * will always have underlying mutex locked.
           *
           * @param lock Lock object grabbed by the client_state
           */
          virtual bool interrupted(wsrep::unique_lock<wsrep::mutex>& lock) const = 0;
  
          /**
           * Reset possible global or thread local parameters associated
           * to the thread.
           */
          virtual void reset_globals() = 0;
  
          /**
           * Store possible global or thread local parameters associated
           * to the thread.
           */
          virtual void store_globals() = 0;
  
          /**
           * Set up a data for replication.
           */
          virtual int prepare_data_for_replication() = 0;
  
          /**
           * Clean up after transcation has been terminated.
           */
          virtual void cleanup_transaction() = 0;
  
          //
          // Streaming
          //
          /**
           * Return true if current statement is allowed for streaming,
           * otherwise false.
           */
          virtual bool statement_allowed_for_streaming() const = 0;
  
          /**
           * Return the total number of bytes generated by the transaction
           * context.
           */
          virtual size_t bytes_generated() const = 0;
  
          /**
           * Prepare a buffer containing data for the next fragment to replicate.
           * The caller may set log_position to record the database specific
           * position corresponding to changes contained in the buffer.
           * When the call returns, the log_position will be available to read
           * from streaming_context::log_position().
           *
           * @return Zero in case of success, non-zero on failure.
           *         If there is no data to replicate, the method shall return
           *         zero and leave the buffer empty.
           */
          virtual int prepare_fragment_for_replication(wsrep::mutable_buffer& buffer,
                                                       size_t& log_position) = 0;
  
          /**
           * Remove fragments from the storage within current transaction.
           * Fragment removal will be committed once the current transaction
           * commits.
           *
           * @return Zero in case of success, non-zero on failure.
           */
          virtual int remove_fragments() = 0;
  
          //
          // Rollback
          //
          /**
           * Perform brute force rollback.
           *
           * This method may be called from two contexts, either from
           * client state methods when the BF abort condition is detected,
           * or from the background rollbacker thread. The task for this
           * method is to release all reasources held by the client
           * after BF abort so that the high priority thread can continue
           * applying.
           */
          virtual int bf_rollback() = 0;
  
          //
          // Interface to global server state
          //
          /**
           * Forcefully shut down the DBMS process or replication system.
           * This may be called in situations where
           * the process may encounter a situation where data integrity
           * may not be guaranteed or other unrecoverable condition is
           * encontered.
           */
          virtual void emergency_shutdown() = 0;
  
          // Replaying
          /**
           * Notify that the client will replay.
           *
           * @todo This should not be visible to DBMS level, should be
           * handled internally by wsrep-lib.
           */
          virtual void will_replay() = 0;
  
          /**
           * Signal that replay is done.
           */
          virtual void signal_replayed() = 0;
  
          /**
           * Replay the current transaction. The implementation must put
           * the caller Client Context into applying mode and call
           * client_state::replay().
           *
           * @todo This should not be visible to DBMS level, should be
           * handled internally by wsrep-lib.
           */
          virtual enum wsrep::provider::status replay() = 0;
  
          /**
           * Replay the current transaction. This is used for replaying
           * prepared XA transactions, which are BF aborted but not
           * while orderding commit / rollback.
           */
          virtual enum wsrep::provider::status replay_unordered() = 0;
  
          /**
           * Wait until all replaying transactions have been finished
           * replaying.
           *
           * @todo This should not be visible to DBMS level, should be
           * handled internally by wsrep-lib.
           */
          virtual void wait_for_replayers(wsrep::unique_lock<wsrep::mutex>&) = 0;
  
          //
          // XA
          //
          /**
           * Send a commit by xid
           */
          virtual enum wsrep::provider::status commit_by_xid() = 0;
  
          /**
           * Returns true if the client has an ongoing XA transaction.
           * This method is used to determine when to cleanup the
           * corresponding wsrep-lib transaction object.
           * This method should return false when the XA transaction
           * is over, and the wsrep-lib transaction object can be
           * cleaned up.
           */
          virtual bool is_explicit_xa() = 0;
  
          /**
           * Returns true if the currently executing command is
           * a rollback for XA. This is used to avoid setting a
           * a deadlock error rollback as it may be unexpected
           * by the DBMS.
           */
          virtual bool is_xa_rollback() = 0;
  
          //
          // Debug interface
          //
          /**
           * Enter debug sync point.
           *
           * @params sync_point Name of the debug sync point.
           */
          virtual void debug_sync(const char* sync_point) = 0;
  
          /**
           * Forcefully kill the process if the crash_point has
           * been enabled.
           */
          virtual void debug_crash(const char* crash_point) = 0;
      };
  }
  
  #endif // WSREP_CLIENT_SERVICE_HPP
  