pdserving.cpp 7.7 KB
Newer Older
W
wangguibao 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

W
serving  
wangguibao 已提交
15
#include <sys/stat.h>
W
wangguibao 已提交
16
#include <sys/types.h>
W
serving  
wangguibao 已提交
17 18
#include <unistd.h>

W
wangguibao 已提交
19 20 21
#ifdef BCLOUD
#include <bthread_unstable.h>  // bthread_set_worker_startfn
#else
W
wangguibao 已提交
22
#include <bthread/unstable.h>  // bthread_set_worker_startfn
W
wangguibao 已提交
23 24
#endif

W
wangguibao 已提交
25
#include <fstream>
W
wangguibao 已提交
26
#include <iostream>
W
wangguibao 已提交
27

G
guru4elephant 已提交
28 29 30 31 32 33 34
#include "core/predictor/common/constant.h"
#include "core/predictor/common/inner_common.h"
#include "core/predictor/framework/manager.h"
#include "core/predictor/framework/resource.h"
#include "core/predictor/framework/server.h"
#include "core/predictor/framework/service.h"
#include "core/predictor/framework/workflow.h"
W
wangguibao 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

using baidu::paddle_serving::predictor::ServerManager;
using baidu::paddle_serving::predictor::WorkflowManager;
using baidu::paddle_serving::predictor::InferServiceManager;
using baidu::paddle_serving::predictor::Resource;
using baidu::paddle_serving::predictor::FLAGS_workflow_path;
using baidu::paddle_serving::predictor::FLAGS_workflow_file;
using baidu::paddle_serving::predictor::FLAGS_inferservice_path;
using baidu::paddle_serving::predictor::FLAGS_inferservice_file;
using baidu::paddle_serving::predictor::FLAGS_logger_path;
using baidu::paddle_serving::predictor::FLAGS_logger_file;
using baidu::paddle_serving::predictor::FLAGS_resource_path;
using baidu::paddle_serving::predictor::FLAGS_resource_file;
using baidu::paddle_serving::predictor::FLAGS_reload_interval_s;
using baidu::paddle_serving::predictor::FLAGS_port;

W
wangguibao 已提交
51 52 53
using baidu::paddle_serving::configure::InferServiceConf;
using baidu::paddle_serving::configure::read_proto_conf;

W
wangguibao 已提交
54 55
void print_revision(std::ostream& os, void*) {
#if defined(PDSERVING_VERSION)
W
wangguibao 已提交
56
  os << PDSERVING_VERSION;
W
wangguibao 已提交
57
#else
W
wangguibao 已提交
58
  os << "undefined";
W
wangguibao 已提交
59 60
#endif
#if defined(PDSERVING_BUILDTIME)
W
wangguibao 已提交
61
  os << ", BuildAt: " << PDSERVING_BUILDTIME;
W
wangguibao 已提交
62 63 64 65
#endif
}

static bvar::PassiveStatus<std::string> s_predictor_revision(
W
wangguibao 已提交
66
    "predictor_revision", print_revision, NULL);
W
wangguibao 已提交
67

W
wangguibao 已提交
68
DEFINE_bool(V, false, "print version, bool");
W
wangguibao 已提交
69 70 71
DEFINE_bool(g, false, "user defined gflag path");
DECLARE_string(flagfile);

72 73
//
/*
74
namespace bthread {
W
wangguibao 已提交
75
extern pthread_mutex_t g_task_control_mutex;
76
}
77
pthread_mutex_t g_worker_start_fn_mutex = PTHREAD_MUTEX_INITIALIZER;
78
*/
79
void pthread_worker_start_fn() {
80
  /*
W
wangguibao 已提交
81 82
  while (pthread_mutex_lock(&g_worker_start_fn_mutex) != 0) {
  }
83 84 85 86 87 88

  // Try to avoid deadlock in bthread
  int lock_status = pthread_mutex_trylock(&bthread::g_task_control_mutex);
  if (lock_status == EBUSY || lock_status == EAGAIN) {
    pthread_mutex_unlock(&bthread::g_task_control_mutex);
  }
89
  */
90
  Resource::instance().thread_initialize();
91 92

  // Try to avoid deadlock in bthread
93
  /*
94
  if (lock_status == EBUSY || lock_status == EAGAIN) {
W
wangguibao 已提交
95 96
    while (pthread_mutex_lock(&bthread::g_task_control_mutex) != 0) {
    }
97 98 99
  }

  pthread_mutex_unlock(&g_worker_start_fn_mutex);
100
  */
101
}
W
wangguibao 已提交
102 103

static void g_change_server_port() {
W
wangguibao 已提交
104 105 106 107
  InferServiceConf conf;
  if (read_proto_conf(FLAGS_inferservice_path.c_str(),
                      FLAGS_inferservice_file.c_str(),
                      &conf) != 0) {
B
barrierye 已提交
108 109
    VLOG(2) << "failed to load configure[" << FLAGS_inferservice_path << ","
            << FLAGS_inferservice_file << "].";
W
wangguibao 已提交
110
    return;
W
wangguibao 已提交
111 112 113 114
  }
  uint32_t port = conf.port();
  if (port != 0) {
    FLAGS_port = port;
115 116 117
    VLOG(2) << "use configure[" << FLAGS_inferservice_path << "/"
            << FLAGS_inferservice_file << "] port[" << port
            << "] instead of flags";
W
wangguibao 已提交
118 119
  }
  return;
W
wangguibao 已提交
120 121 122 123
}

#ifdef UNIT_TEST
int ut_main(int argc, char** argv) {
W
wangguibao 已提交
124
#else
W
wangguibao 已提交
125 126
int main(int argc, char** argv) {
#endif
W
wangguibao 已提交
127
  google::ParseCommandLineFlags(&argc, &argv, true);
W
wangguibao 已提交
128

W
wangguibao 已提交
129 130 131 132 133
  if (FLAGS_V) {
    print_revision(std::cout, NULL);
    std::cout << std::flush;
    return 0;
  }
W
wangguibao 已提交
134

135
  // google::ParseCommandLineFlags(&argc, &argv, true);
W
wangguibao 已提交
136

W
wangguibao 已提交
137
  g_change_server_port();
W
wangguibao 已提交
138

W
wangguibao 已提交
139
// initialize logger instance
W
wangguibao 已提交
140 141 142 143 144 145
#ifdef BCLOUD
  logging::LoggingSettings settings;
  settings.logging_dest = logging::LOG_TO_FILE;

  std::string filename(argv[0]);
  filename = filename.substr(filename.find_last_of('/') + 1);
146 147
  settings.log_file =
      strdup((std::string("./log/") + filename + ".log").c_str());
W
wangguibao 已提交
148 149 150 151 152 153 154 155
  settings.delete_old = logging::DELETE_OLD_LOG_FILE;
  logging::InitLogging(settings);

  logging::ComlogSinkOptions cso;
  cso.process_name = filename;
  cso.enable_wf_device = true;
  logging::ComlogSink::GetInstance()->Setup(&cso);
#else
W
wangguibao 已提交
156 157 158
  if (FLAGS_log_dir == "") {
    FLAGS_log_dir = "./log";
  }
W
wangguibao 已提交
159

W
wangguibao 已提交
160 161
  struct stat st_buf;
  int ret = 0;
W
wangguibao 已提交
162 163 164
  if ((ret = stat(FLAGS_log_dir.c_str(), &st_buf)) != 0) {
    mkdir(FLAGS_log_dir.c_str(), 0777);
    ret = stat(FLAGS_log_dir.c_str(), &st_buf);
W
wangguibao 已提交
165
    if (ret != 0) {
B
barrierye 已提交
166
      VLOG(2) << "Log path " << FLAGS_log_dir << " not exist, and create fail";
W
wangguibao 已提交
167
      return -1;
W
wangguibao 已提交
168
    }
W
wangguibao 已提交
169 170
  }
  google::InitGoogleLogging(strdup(argv[0]));
W
wangguibao 已提交
171 172
  FLAGS_logbufsecs = 0;
  FLAGS_logbuflevel = -1;
W
wangguibao 已提交
173
#endif
174
  VLOG(2) << "Succ initialize logger";
W
wangguibao 已提交
175 176 177 178 179 180 181 182

  // initialize resource manager
  if (Resource::instance().initialize(FLAGS_resource_path,
                                      FLAGS_resource_file) != 0) {
    LOG(ERROR) << "Failed initialize resource, conf:" << FLAGS_resource_path
               << "/" << FLAGS_resource_file;
    return -1;
  }
183
  VLOG(2) << "Succ initialize resource";
W
wangguibao 已提交
184 185 186 187 188 189 190 191

  // initialize workflow manager
  if (WorkflowManager::instance().initialize(FLAGS_workflow_path,
                                             FLAGS_workflow_file) != 0) {
    LOG(ERROR) << "Failed initialize workflow manager, conf:"
               << FLAGS_workflow_path << "/" << FLAGS_workflow_file;
    return -1;
  }
192
  VLOG(2) << "Succ initialize workflow";
W
wangguibao 已提交
193 194 195 196 197 198 199 200

  // initialize service manager
  if (InferServiceManager::instance().initialize(
          FLAGS_inferservice_path, FLAGS_inferservice_file) != 0) {
    LOG(ERROR) << "Failed initialize infer service manager, conf:"
               << FLAGS_inferservice_path << "/" << FLAGS_inferservice_file;
    return -1;
  }
201
  VLOG(2) << "Succ initialize inferservice";
W
wangguibao 已提交
202 203 204 205 206 207 208

  int errcode = bthread_set_worker_startfn(pthread_worker_start_fn);
  if (errcode != 0) {
    LOG(ERROR) << "Failed call pthread worker start function, error_code["
               << errcode << "]";
    return -1;
  }
209
  VLOG(2) << "Succ call pthread worker start function";
W
wangguibao 已提交
210

211
  // this is not used by any code segment,which can be cancelled.
212 213
  if (Resource::instance().general_model_initialize(FLAGS_resource_path,
                                                    FLAGS_resource_file) != 0) {
G
guru4elephant 已提交
214
    LOG(ERROR) << "Failed to initialize general model conf: "
215
               << FLAGS_resource_path << "/" << FLAGS_resource_file;
G
guru4elephant 已提交
216 217 218
    return -1;
  }

219
  VLOG(2) << "Succ initialize general model";
G
guru4elephant 已提交
220

221
#ifndef BCLOUD
W
wangguibao 已提交
222 223
  // FATAL messages are output to stderr
  FLAGS_stderrthreshold = 3;
W
wangguibao 已提交
224
#endif
W
wangguibao 已提交
225

W
wangguibao 已提交
226 227 228 229
  if (ServerManager::instance().start_and_wait() != 0) {
    LOG(ERROR) << "Failed start server and wait!";
    return -1;
  }
230
  VLOG(2) << "Succ start service manager";
W
wangguibao 已提交
231 232 233 234 235 236 237 238 239 240 241 242 243

  if (InferServiceManager::instance().finalize() != 0) {
    LOG(ERROR) << "Failed finalize infer service manager.";
  }

  if (WorkflowManager::instance().finalize() != 0) {
    LOG(ERROR) << "Failed finalize workflow manager";
  }

  if (Resource::instance().finalize() != 0) {
    LOG(ERROR) << "Failed finalize resource manager";
  }

W
wangguibao 已提交
244 245
#ifdef BCLOUD
#else
W
wangguibao 已提交
246
  google::ShutdownGoogleLogging();
W
wangguibao 已提交
247
#endif
248
  VLOG(2) << "Paddle Inference Server exit successfully!";
W
wangguibao 已提交
249
  return 0;
W
wangguibao 已提交
250
}