WebServiceRunner.h
Go to the documentation of this file.
00001 /* 00002 * Copyright 2006-2009 Savarese Software Research Corporation 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * https://www.savarese.com/software/ApacheLicense-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00023 #ifndef __SSRC_WSPR_WS_WEB_SERVICE_RUNNER_H 00024 #define __SSRC_WSPR_WS_WEB_SERVICE_RUNNER_H 00025 00026 #include <ssrc/wispers/ws/service.h> 00027 #include <ssrc/wispers/ws/WebServiceModule.h> 00028 #include <ssrc/wispers/utility/DynamicLibrary.h> 00029 00030 __BEGIN_NS_SSRC_WSPR_WS 00031 00032 using NS_SSRC_WSPR_UTILITY::LoadError; 00033 using NS_SSRC_WSPR_UTILITY::DynamicLibrary; 00034 00035 namespace detail { 00036 extern "C" typedef void fun_delete_module(WebServiceModule *); 00037 extern "C" typedef fun_delete_module* fun_ptr_delete_module; 00038 00039 class WebServiceModuleDeleter { 00040 fun_ptr_delete_module _delete_module; 00041 00042 public: 00043 explicit WebServiceModuleDeleter(const fun_ptr_delete_module delete_module) : 00044 _delete_module(delete_module) 00045 { } 00046 00047 void operator()(WebServiceModule *module) const { 00048 _delete_module(module); 00049 } 00050 }; 00051 00052 template<typename PT = BinaryPackingTraits> 00053 class WebServiceModuleFactory { 00054 typedef NS_SSRC_WISP_PROTOCOL::ContinuationCaller<PT> caller_type; 00055 00056 // Should really be extern "C", but we can only do that in namespace scope. 00057 typedef WebServiceModule* fun_new_module(const ws_module_context_ptr &); 00058 typedef fun_new_module* fun_ptr_new_module; 00059 00060 DynamicLibrary _lib; 00061 fun_ptr_new_module _new_module; 00062 fun_ptr_delete_module _delete_module; 00063 00064 public: 00065 00066 typedef boost::shared_ptr<WebServiceModule> ws_module_ptr; 00067 00068 #define WS_MODULE_SYM_NEW "ws_module_new" 00069 #define WS_MODULE_SYM_DELETE "ws_module_delete" 00070 00071 explicit WebServiceModuleFactory(const string & filename, 00072 const DynamicLibrary::Mode mode = 00073 DynamicLibrary::NowLocal) 00074 SSRC_DECL_THROW(LoadError) : 00075 _lib(filename, mode), 00076 _new_module(_lib.symbol<fun_ptr_new_module>(WS_MODULE_SYM_NEW)), 00077 _delete_module(_lib.symbol<fun_ptr_delete_module>(WS_MODULE_SYM_DELETE)) 00078 { } 00079 00080 #undef WS_MODULE_SYM_NEW 00081 #undef WS_MODULE_SYM_DELETE 00082 00083 ws_module_ptr new_module(const ws_module_context_ptr & context) { 00084 if(_new_module && _delete_module) 00085 return 00086 ws_module_ptr(_new_module(context), 00087 WebServiceModuleDeleter(_delete_module)); 00088 00089 return ws_module_ptr(); 00090 } 00091 }; 00092 } 00093 00094 struct WebServiceRunnerInitializer { 00095 typedef std::vector<string> dir_list; 00096 dir_list module_dirs; 00097 Properties actions; 00098 }; 00099 00100 struct WebServiceModuleConfig { 00101 string name; 00102 string module; 00103 string type; 00104 Properties properties; 00105 00106 WebServiceModuleConfig(const string & name, 00107 const string & module, 00108 const string & type, 00109 const Properties & properties) : 00110 name(name), module(module), type(type), properties(properties) 00111 { } 00112 }; 00113 00114 template<typename container_type> 00115 void get_ws_module_configs(container_type & result, const Properties & modules) 00116 { 00117 const Properties *p = modules.find("Module"); 00118 00119 if(p != 0) { 00120 Properties::child_container_const_iterator && it = p->child_begin(); 00121 Properties::child_container_const_iterator && end = p->child_end(); 00122 00123 while(it != end) { 00124 const string & name = it->first; 00125 const Properties *node = it->second; 00126 const string & module = node->get<string>("", "module"); 00127 const string & type = node->get<string>("", "type"); 00128 result.push_back(WebServiceModuleConfig(name, module, type, 00129 *node->find("properties"))); 00130 ++it; 00131 } 00132 } 00133 } 00134 00135 class WebServiceRunner : public WebService { 00136 typedef WebService super; 00137 friend class NS_SSRC_WISP_SERVICE::ServiceProtocolProcessor<packing_traits>; 00138 00139 typedef detail::WebServiceModuleFactory<packing_traits> ws_module_factory; 00140 typedef boost::shared_ptr<ws_module_factory> ws_module_factory_ptr; 00141 00142 WISP_IMPORT(ws_module_factory, ws_module_ptr); 00143 00144 struct ws_module_entry { 00145 // Important: must be first so it is destroyed after module. 00146 ws_module_factory_ptr factory; 00147 ws_module_ptr module; 00148 00149 ws_module_entry(const ws_module_factory_ptr & factory, 00150 const ws_module_ptr & module) : 00151 factory(factory), module(module) 00152 { } 00153 }; 00154 00155 typedef std::unordered_map<string, ws_module_entry> ws_module_map; 00156 00157 WebServiceRunnerInitializer::dir_list _module_dirs; 00158 std::vector<WebServiceModuleConfig> _module_configs; 00159 ws_module_map _module_map; 00160 00161 static ws_module_factory_ptr 00162 new_module_factory(const string & filename, 00163 const DynamicLibrary::Mode mode = 00164 DynamicLibrary::NowLocal) 00165 { 00166 return 00167 ws_module_factory_ptr(new ws_module_factory(filename, mode)); 00168 } 00169 00170 void load_modules() SSRC_DECL_THROW(LoadError); 00171 00175 virtual void transition(State state) { 00176 switch(state) { 00177 case Starting: 00178 load_modules(); 00179 state = Started; 00180 break; 00181 case Stopping: 00182 state = Stopped; 00183 break; 00184 default: 00185 break; 00186 } 00187 00188 super::transition(state); 00189 } 00190 00191 public: 00192 00193 WebServiceRunner(caller_type & caller, 00194 const WebServiceRunnerInitializer & initializer) : 00195 super(caller), _module_dirs(initializer.module_dirs) 00196 { 00197 super::add_service_type(WSPR_WS_TYPE("runner")); 00198 get_ws_module_configs(_module_configs, initializer.actions); 00199 get_actions(_actions, initializer.actions); 00200 } 00201 00202 virtual ~WebServiceRunner() { 00203 // All references to dynamically loaded memory must be removed since 00204 // call handler maps are destroyed after unloading dynamic library. 00205 clear_call_handlers(); 00206 clear_request_handlers(); 00207 clear_response_handlers(); 00208 // Even though these may be redundant because they happen when a 00209 // service enters the stopped state, we want to make sure that no 00210 // continuations or timeouts reference module memory spaces. 00211 clear_timeouts(); 00212 _caller.cancel_all(); 00213 } 00214 }; 00215 00216 __END_NS_SSRC_WSPR_WS 00217 00218 #endif
Copyright © 2006-2011 Savarese Software Research Corporation. All rights reserved.