bool LogManager::Open(const std::string& path){ path_ = path; abb::Mutex::Locker l(mtx_); fd_ = open(path.c_str(),O_RDWR,0600); if(fd_ < 0){ LOG(WARN)<< "raft.open.file.failed:"<<path<< " err:" <<errno<<" errstr:" << strerror(errno); fd_ = open(path.c_str(),O_RDWR|O_CREAT,0600); if(fd_ < 0){ LOG(WARN)<< "raft.create.file.failed:"<<path<< " err:" <<errno<<" errstr:" << strerror(errno); return false; } LOG(DEBUG)<< "log.open.create " << path; return true; } fcntl(fd_, F_SETFD, FD_CLOEXEC); LOG(DEBUG)<< "log.open.exist " << path; lseek(fd_,0,SEEK_SET); abb::Buffer buf; while( buf.WriteFromeReader(StaticReader,this) > 0){ ; } int position = 0; int size = buf.ReadSize(); while(size > 0){ LogEntry* entry = new LogEntry(); if( ! entry->Decode(buf) ) { entry->UnRef(); return false; } entry->position = position; if(entry->index_ > this->start_index_){ entry->Ref(); this->log_entry_arr_.push_back(entry); if(entry->index_ <= this->commit_index_){ entry->cmd_->Apply(this->svr_,NULL,NULL); } } position += size - buf.ReadSize(); entry->UnRef(); size = buf.ReadSize(); } if(this->log_entry_arr_.size() > 0){ LOG(DEBUG) << "open.log.append log index " << this->log_entry_arr_.front()->index_ << ":" <<this->log_entry_arr_.back()->index_ << " " << this->commit_index_; } return true; }
bool LogManager::CommitToIndex(uint64_t index){ LogEntryArray arr; { LOG(TRACE) << "CommitToIndex" << index; abb::Mutex::Locker l(mtx_); if(index > (log_entry_arr_.size() + start_index_)){ LOG(DEBUG) << "raft.Log: Commit index" << index << "set back to " << ( log_entry_arr_.size() + start_index_); index = log_entry_arr_.size() + start_index_; } if (index < commit_index_) { LOG(DEBUG) << "raft.Log: Commit index earily :" << index << "commit_index_:" << commit_index_; return true; } for(unsigned i= this->commit_index_+1;i<=index;i++){ int e_index = i - 1 - this->start_index_; LogEntry* entry = log_entry_arr_[e_index]; this->commit_index_ = entry->index_; entry->Ref(); arr.push_back(entry); } } for(unsigned i = 0;i< arr.size();i++){ LogEntry* entry = arr[i]; if(entry->ev_){ IMessage* msg = NULL; std::string error ; entry->cmd_->Apply(this->svr_,&error,&msg); entry->ev_->Notify(msg,error); entry->ev_->UnRef(); entry->ev_ = NULL; }else{ entry->cmd_->Apply(this->svr_,NULL,NULL); } entry->UnRef(); } return true; }
bool LogManager::AppendEntries(LogEntryArray entries,std::string* save_err){ abb::Mutex::Locker l(mtx_); for(unsigned i=0;i<entries.size();i++){ LogEntry* entry = entries[i]; if(this->log_entry_arr_.size() > 0){ LogEntry* last_entry = this->log_entry_arr_.back(); if(last_entry->term_ > entry->term_){ LOG(DEBUG) << "Cannot Append entry with earlier term last:" << last_entry->term_ << "insert:" << entry->term_; if(save_err) *save_err = "Cannot Append entry with earlier term"; return false; }else if(last_entry->term_ == entry->term_ && entry->index_ < last_entry->index_){ LOG(DEBUG) << "Cannot Append entry with earlier index in same term last:" << last_entry->index_ << "insert:" << entry->index_; if(save_err) *save_err = "Cannot Append entry with earlier index"; return false; } } entry->Ref(); WriteEntry(fd_,entry); this->log_entry_arr_.push_back(entry); } if(entries.size() > 0) fsync(fd_); return true; }