| 312 | } |
| 313 | |
| 314 | bool TabletNodeImpl::Exit() { |
| 315 | running_ = false; |
| 316 | exit_event_.Set(); |
| 317 | |
| 318 | cache_metrics_.reset(NULL); |
| 319 | |
| 320 | std::vector<io::TabletIO*> tablet_ios; |
| 321 | tablet_manager_->GetAllTablets(&tablet_ios); |
| 322 | |
| 323 | std::vector<std::thread> unload_threads; |
| 324 | unload_threads.reserve(tablet_ios.size()); |
| 325 | |
| 326 | Counter worker_count; |
| 327 | worker_count.Set(tablet_ios.size()); |
| 328 | |
| 329 | for (uint32_t i = 0; i < tablet_ios.size(); ++i) { |
| 330 | io::TabletIO* tablet_io = tablet_ios[i]; |
| 331 | unload_threads.emplace_back( |
| 332 | std::bind(&TabletNodeImpl::UnloadTabletProc, this, tablet_io, &worker_count)); |
| 333 | } |
| 334 | int64_t print_ms_ = get_millis(); |
| 335 | int64_t left = 0; |
| 336 | while ((left = worker_count.Get()) > 0) { |
| 337 | if (get_millis() - print_ms_ > 1000) { |
| 338 | LOG(INFO) << "[Exit] " << left << " tablets are still unloading ..."; |
| 339 | print_ms_ = get_millis(); |
| 340 | } |
| 341 | ThisThread::Sleep(100); |
| 342 | } |
| 343 | for (uint32_t i = 0; i < tablet_ios.size(); ++i) { |
| 344 | unload_threads[i].join(); |
| 345 | } |
| 346 | tablet_healthcheck_thread_.join(); |
| 347 | |
| 348 | std::unique_ptr<leveldb::Logger> logger(leveldb::Logger::DefaultLogger()); |
| 349 | if (logger) { |
| 350 | logger->Exit(); |
| 351 | } |
| 352 | |
| 353 | zk_adapter_->Exit(); |
| 354 | return true; |
| 355 | } |
| 356 | |
| 357 | void TabletNodeImpl::RefreshTabletsStatus() { |
| 358 | while (running_) { |