pdserving.cpp 7.6 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
namespace bthread {
W
wangguibao 已提交
73
extern pthread_mutex_t g_task_control_mutex;
74
}
75
pthread_mutex_t g_worker_start_fn_mutex = PTHREAD_MUTEX_INITIALIZER;
76 77

void pthread_worker_start_fn() {
W
wangguibao 已提交
78 79
  while (pthread_mutex_lock(&g_worker_start_fn_mutex) != 0) {
  }
80 81 82 83 84 85

  // 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);
  }
86
  Resource::instance().thread_initialize();
87 88 89

  // Try to avoid deadlock in bthread
  if (lock_status == EBUSY || lock_status == EAGAIN) {
W
wangguibao 已提交
90 91
    while (pthread_mutex_lock(&bthread::g_task_control_mutex) != 0) {
    }
92 93 94
  }

  pthread_mutex_unlock(&g_worker_start_fn_mutex);
95
}
W
wangguibao 已提交
96 97

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

#ifdef UNIT_TEST
int ut_main(int argc, char** argv) {
W
wangguibao 已提交
118
#else
W
wangguibao 已提交
119 120
int main(int argc, char** argv) {
#endif
W
wangguibao 已提交
121
  google::ParseCommandLineFlags(&argc, &argv, true);
W
wangguibao 已提交
122

W
wangguibao 已提交
123 124 125 126 127
  if (FLAGS_V) {
    print_revision(std::cout, NULL);
    std::cout << std::flush;
    return 0;
  }
W
wangguibao 已提交
128

W
wangguibao 已提交
129
  google::ParseCommandLineFlags(&argc, &argv, true);
W
wangguibao 已提交
130

W
wangguibao 已提交
131
  g_change_server_port();
W
wangguibao 已提交
132

W
wangguibao 已提交
133
// initialize logger instance
W
wangguibao 已提交
134 135 136 137 138 139
#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);
140 141
  settings.log_file =
      strdup((std::string("./log/") + filename + ".log").c_str());
W
wangguibao 已提交
142 143 144 145 146 147 148 149
  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 已提交
150 151 152
  if (FLAGS_log_dir == "") {
    FLAGS_log_dir = "./log";
  }
W
wangguibao 已提交
153

W
wangguibao 已提交
154 155
  struct stat st_buf;
  int ret = 0;
W
wangguibao 已提交
156 157 158
  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 已提交
159
    if (ret != 0) {
B
barrierye 已提交
160
      VLOG(2) << "Log path " << FLAGS_log_dir << " not exist, and create fail";
W
wangguibao 已提交
161
      return -1;
W
wangguibao 已提交
162
    }
W
wangguibao 已提交
163 164
  }
  google::InitGoogleLogging(strdup(argv[0]));
W
wangguibao 已提交
165 166
  FLAGS_logbufsecs = 0;
  FLAGS_logbuflevel = -1;
W
wangguibao 已提交
167
#endif
168
  VLOG(2) << "Succ initialize logger";
W
wangguibao 已提交
169 170 171 172 173 174 175 176

  // 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;
  }
177
  VLOG(2) << "Succ initialize resource";
W
wangguibao 已提交
178 179 180 181 182 183 184 185

  // 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;
  }
186
  VLOG(2) << "Succ initialize workflow";
W
wangguibao 已提交
187 188 189 190 191 192 193 194

  // 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;
  }
195
  VLOG(2) << "Succ initialize inferservice";
W
wangguibao 已提交
196 197 198 199 200 201 202

  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;
  }
203
  VLOG(2) << "Succ call pthread worker start function";
W
wangguibao 已提交
204

W
wangguibao 已提交
205
#ifndef BCLOUD
G
guru4elephant 已提交
206

207 208
  if (Resource::instance().general_model_initialize(FLAGS_resource_path,
                                                    FLAGS_resource_file) != 0) {
G
guru4elephant 已提交
209
    LOG(ERROR) << "Failed to initialize general model conf: "
210
               << FLAGS_resource_path << "/" << FLAGS_resource_file;
G
guru4elephant 已提交
211 212 213
    return -1;
  }

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

W
wangguibao 已提交
216 217
  // FATAL messages are output to stderr
  FLAGS_stderrthreshold = 3;
W
wangguibao 已提交
218
#endif
W
wangguibao 已提交
219

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

  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 已提交
238 239
#ifdef BCLOUD
#else
W
wangguibao 已提交
240
  google::ShutdownGoogleLogging();
W
wangguibao 已提交
241
#endif
242
  VLOG(2) << "Paddle Inference Server exit successfully!";
W
wangguibao 已提交
243
  return 0;
W
wangguibao 已提交
244
}