You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2013/07/19 00:32:57 UTC
git commit: TS-1487: Fix startup order, add lifecycle hooks
Updated Branches:
refs/heads/master ea560cecc -> 941784b2a
TS-1487: Fix startup order, add lifecycle hooks
Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/941784b2
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/941784b2
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/941784b2
Branch: refs/heads/master
Commit: 941784b2a1ff3bcaf8a9a78337dbf121d6a21cf6
Parents: ea560ce
Author: Alan M. Carroll <am...@network-geographics.com>
Authored: Thu Jul 18 09:25:42 2013 -0500
Committer: Alan M. Carroll <am...@network-geographics.com>
Committed: Thu Jul 18 17:32:21 2013 -0500
----------------------------------------------------------------------
CHANGES | 2 +
configure.ac | 13 --
example/Makefile.am | 2 +
example/app-template/app-template.cc | 4 -
example/lifecycle-plugin/lifecycle-plugin.c | 116 +++++++++++++++
example/lifecycle-plugin/readme.txt | 1 +
iocore/cache/Cache.cc | 3 +
iocore/cache/I_Cache.h | 25 ++++
lib/ts/ink_config.h.in | 7 -
mgmt/RecordsConfig.cc | 2 +
proxy/IPAllow.h | 1 -
proxy/InkAPI.cc | 73 +++-------
proxy/InkAPIInternal.h | 89 ++++++++++--
proxy/Main.cc | 65 +++++++--
proxy/Transform.cc | 4 -
proxy/api/ts/ts.h.in | 55 +++++++
proxy/http/HttpClientSession.cc | 2 +-
proxy/http/HttpProxyServerMain.cc | 176 +++++++++++++++--------
proxy/http/HttpProxyServerMain.h | 8 +-
proxy/http/HttpSM.cc | 2 +-
proxy/http/HttpTransact.cc | 4 -
proxy/http/HttpUpdateSM.cc | 2 -
22 files changed, 476 insertions(+), 180 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 599f7bf..d6889d8 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,8 @@
-*- coding: utf-8 -*-
Changes with Apache Traffic Server 3.3.5
+ *) [TS-1487] [TS-2035] Moved plugin init, added plugin lifecycle hooks, added delay listen for cache. Removed TS_NO_API defined/build option.
+
*) [TS-2047] Schedule RamCacheCLFUSCompressor in RamCacheCLFUS::init instead
of immediatly after instantiation.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index 0bc7a00..0d2285a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -279,19 +279,6 @@ AC_MSG_RESULT([$enable_remote_cov_commit])
AC_SUBST([enable_remote_cov_commit])
#
-# API
-#
-AC_MSG_CHECKING([whether to enable API and plugin support])
-AC_ARG_ENABLE([api],
- [AS_HELP_STRING([--disable-api],[do not enable API and plugin support])],
- [],
- [enable_api=yes]
-)
-AC_MSG_RESULT([$enable_api])
-AS_IF([test "x$enable_api" = "xyes"], [has_inkapi=1], [has_inkapi=0])
-AC_SUBST(has_inkapi)
-
-#
# WCCP
#
AC_MSG_CHECKING([whether to enable WCCP v2 support])
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/example/Makefile.am
----------------------------------------------------------------------
diff --git a/example/Makefile.am b/example/Makefile.am
index e0939e0..193e1c4 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -28,6 +28,7 @@ noinst_LTLIBRARIES = \
cache-scan.la \
file-1.la \
hello.la \
+ lifecycle-plugin.la \
null-transform.la \
output-header.la \
protocol.la \
@@ -48,6 +49,7 @@ bnull_transform_la_SOURCES = bnull-transform/bnull-transform.c
cache_scan_la_SOURCES = cache-scan/cache-scan.cc
file_1_la_SOURCES = file-1/file-1.c
hello_la_SOURCES = hello/hello.c
+lifecycle_plugin_la_SOURCES = lifecycle-plugin/lifecycle-plugin.c
null_transform_la_SOURCES = null-transform/null-transform.c
output_header_la_SOURCES = output-header/output-header.c
protocol_la_SOURCES = protocol/Protocol.c protocol/TxnSM.c
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/example/app-template/app-template.cc
----------------------------------------------------------------------
diff --git a/example/app-template/app-template.cc b/example/app-template/app-template.cc
index cb1d9c3..d4d63cd 100644
--- a/example/app-template/app-template.cc
+++ b/example/app-template/app-template.cc
@@ -232,11 +232,7 @@ int main(int argc, char * argv[])
// initialize logging (after event and net processor)
//Log::init(system_remote_management_flag ? 0 : Log::NO_REMOTE_MANAGEMENT);
-#ifndef TS_NO_API
//plugin_init(system_config_directory); // plugin.config
-#else
- //api_init(); // still need to initialize some of the data structure other module needs.
-#endif
// Create accept continuation
MyAccept *a = new MyAccept;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/example/lifecycle-plugin/lifecycle-plugin.c
----------------------------------------------------------------------
diff --git a/example/lifecycle-plugin/lifecycle-plugin.c b/example/lifecycle-plugin/lifecycle-plugin.c
new file mode 100644
index 0000000..e08fbc3
--- /dev/null
+++ b/example/lifecycle-plugin/lifecycle-plugin.c
@@ -0,0 +1,116 @@
+/** @file
+
+ A brief file description
+
+ @section license License
+
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you 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.
+ */
+
+/* lifecycle-plugin.c: an example plugin to demonstrate the lifecycle hooks.
+ * of response body content
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <ts/ts.h>
+
+// This gets the PRI*64 types
+# define __STDC_FORMAT_MACROS 1
+# include <inttypes.h>
+
+int
+CallbackHandler(TSCont this, TSEvent id, void* no_data) {
+ (void) this;
+ (void) no_data;
+ switch (id) {
+ case TS_EVENT_LIFECYCLE_PORTS_INITIALIZED:
+ TSDebug("lifecycle-plugin", "Proxy ports initialized");
+ break;
+ case TS_EVENT_LIFECYCLE_PORTS_READY:
+ TSDebug("lifecycle-plugin", "Proxy ports active");
+ break;
+ case TS_EVENT_LIFECYCLE_CACHE_READY:
+ TSDebug("lifecycle-plugin", "Cache ready");
+ break;
+ default:
+ TSDebug("lifecycle-plugin", "Unexpected event %d", id);
+ break;
+ }
+ return TS_EVENT_NONE;
+}
+
+int
+CheckVersion()
+{
+ const char *ts_version = TSTrafficServerVersionGet();
+ int result = 0;
+
+ if (ts_version) {
+ int major_ts_version = 0;
+ int minor_ts_version = 0;
+ int patch_ts_version = 0;
+
+ if (sscanf(ts_version, "%d.%d.%d", &major_ts_version, &minor_ts_version, &patch_ts_version) != 3) {
+ return 0;
+ }
+
+ /* Need at least TS 3.3.5 */
+ if (major_ts_version > 3 ||
+ (major_ts_version == 3 &&
+ (minor_ts_version > 3 ||
+ (minor_ts_version == 3 && patch_ts_version >= 5)))) {
+ result = 1;
+ }
+ }
+ return result;
+}
+
+void
+TSPluginInit(int argc, const char *argv[])
+{
+ TSPluginRegistrationInfo info;
+ TSCont cb;
+
+ (void)argc;
+ (void)argv;
+
+ info.plugin_name = "lifecycle-plugin";
+ info.vendor_name = "My Company";
+ info.support_email = "ts-api-support@MyCompany.com";
+
+ if (TSPluginRegister(TS_SDK_VERSION_3_0, &info) != TS_SUCCESS) {
+ TSError("[lifecycle-plugin] Plugin registration failed.\n");
+ goto Lerror;
+ }
+
+ if (!CheckVersion()) {
+ TSError("[lifecycle-plugin] Plugin requires Traffic Server 3.3.5 " "or later\n");
+ goto Lerror;
+ }
+
+ cb = TSContCreate(CallbackHandler, NULL);
+
+ TSLifecycleHookAdd(TS_LIFECYCLE_PORTS_INITIALIZED_HOOK, cb);
+ TSLifecycleHookAdd(TS_LIFECYCLE_PORTS_READY_HOOK, cb);
+ TSLifecycleHookAdd(TS_LIFECYCLE_CACHE_READY_HOOK, cb);
+
+ return;
+
+Lerror:
+ TSError("[amc-tranform] Unable to initialize plugin (disabled).\n");
+}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/example/lifecycle-plugin/readme.txt
----------------------------------------------------------------------
diff --git a/example/lifecycle-plugin/readme.txt b/example/lifecycle-plugin/readme.txt
new file mode 100644
index 0000000..eba37fe
--- /dev/null
+++ b/example/lifecycle-plugin/readme.txt
@@ -0,0 +1 @@
+This prints debug messages about the lifecycle hooks.
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/iocore/cache/Cache.cc
----------------------------------------------------------------------
diff --git a/iocore/cache/Cache.cc b/iocore/cache/Cache.cc
index 9f482fd..06e7edf 100644
--- a/iocore/cache/Cache.cc
+++ b/iocore/cache/Cache.cc
@@ -1084,6 +1084,9 @@ CacheProcessor::cacheInitialized()
CacheProcessor::initialized = CACHE_INIT_FAILED;
Note("cache disabled");
}
+ // Fire callback to signal initialization finished.
+ if (cb_after_init)
+ cb_after_init();
}
void
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/iocore/cache/I_Cache.h
----------------------------------------------------------------------
diff --git a/iocore/cache/I_Cache.h b/iocore/cache/I_Cache.h
index 4b1a3af..00e4791 100644
--- a/iocore/cache/I_Cache.h
+++ b/iocore/cache/I_Cache.h
@@ -65,6 +65,10 @@ typedef HTTPInfo CacheHTTPInfo;
struct CacheProcessor:public Processor
{
+ CacheProcessor()
+ : cb_after_init(0)
+ {}
+
virtual int start(int n_cache_threads = 0, size_t stacksize = DEFAULT_STACKSIZE);
virtual int start_internal(int flags = 0);
void stop();
@@ -132,6 +136,20 @@ struct CacheProcessor:public Processor
static unsigned int IsCacheReady(CacheFragType type);
+ /// Type for callback function.
+ typedef void (*CALLBACK_FUNC)();
+ /** Lifecycle callback.
+
+ The function @a cb is called after cache initialization has
+ finished and the cache is ready or has failed.
+
+ @internal If we need more lifecycle callbacks, this should be
+ generalized ala the standard hooks style, with a type enum used
+ to specific the callback type and passed to the callback
+ function.
+ */
+ void set_after_init_callback(CALLBACK_FUNC cb);
+
// private members
void diskInitialized();
@@ -144,8 +162,15 @@ struct CacheProcessor:public Processor
static int fix;
static int start_internal_flags;
static int auto_clear_flag;
+ CALLBACK_FUNC cb_after_init;
};
+inline void
+CacheProcessor::set_after_init_callback(CALLBACK_FUNC cb)
+{
+ cb_after_init = cb;
+}
+
struct CacheVConnection:public VConnection
{
VIO *do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf) = 0;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/lib/ts/ink_config.h.in
----------------------------------------------------------------------
diff --git a/lib/ts/ink_config.h.in b/lib/ts/ink_config.h.in
index 111c241..b8e59c4 100644
--- a/lib/ts/ink_config.h.in
+++ b/lib/ts/ink_config.h.in
@@ -85,7 +85,6 @@
/* API */
#define TS_IS_MICRO_BUILD @is_micro_build@
#define TS_HAS_STANDALONE_IOCORE @has_standalone_iocore@
-#define TS_HAS_INKAPI @has_inkapi@
#define TS_HAS_DEMANGLE @has_demangle@
#define TS_HAS_TESTS @has_tests@
#define TS_HAS_WCCP @has_wccp@
@@ -111,13 +110,7 @@
#define TS_MAX_HOST_NAME_LEN @max_host_name_len@
-#if TS_HAS_INKAPI
# define TS_MAX_API_STATS @max_api_stats@
-/* XXX: Should make those individually selectable ? */
-#else
-# define TS_NO_TRANSFORM 1
-# define TS_NO_API 1
-#endif
#if TS_HAS_STANDALONE_IOCORE
# define STANDALONE_IOCORE 1
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index f0cc3c8..66102f4 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -390,6 +390,8 @@ RecordElement RecordsConfig[] = {
,
{RECT_CONFIG, "proxy.config.http.server_other_ports", RECD_STRING, NULL, RECU_RESTART_TM, RR_NULL, RECC_NULL, NULL, RECA_NULL}
,
+ {RECT_CONFIG, "proxy.config.http.wait_for_cache", RECD_INT, "1", RECU_RESTART_TM, RR_NULL, RECC_INT, "[0-1]", RECA_NULL}
+ ,
{RECT_CONFIG, "proxy.config.http.insert_request_via_str", RECD_INT, "1", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL}
,
{RECT_CONFIG, "proxy.config.http.insert_response_via_str", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL}
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/IPAllow.h
----------------------------------------------------------------------
diff --git a/proxy/IPAllow.h b/proxy/IPAllow.h
index 941a7e7..76ecdf4 100644
--- a/proxy/IPAllow.h
+++ b/proxy/IPAllow.h
@@ -34,7 +34,6 @@
#include "Main.h"
#include "hdrs/HTTP.h"
#include "ts/IpMap.h"
-#include "vector"
#include "ts/Vec.h"
#include "ProxyConfig.h"
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/InkAPI.cc
----------------------------------------------------------------------
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index cabab42..540bec8 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -21,8 +21,6 @@
limitations under the License.
*/
-#ifndef TS_NO_API
-
// Avoid complaining about the deprecated APIs.
// #define TS_DEPRECATED
@@ -369,6 +367,7 @@ tsapi const char * TS_NPN_PROTOCOL_SPDY_3 = "spdy/3"; // upcoming
tsapi const TSMLoc TS_NULL_MLOC = (TSMLoc)NULL;
HttpAPIHooks *http_global_hooks = NULL;
+LifecycleAPIHooks* lifecycle_hooks = NULL;
ConfigUpdateCbTable *global_config_cbs = NULL;
static char traffic_server_version[128] = "";
@@ -630,6 +629,13 @@ sdk_sanity_check_hook_id(TSHttpHookID id)
return TS_SUCCESS;
}
+TSReturnCode
+sdk_sanity_check_lifecycle_hook_id(TSLifecycleHookID id)
+{
+ if (id<TS_LIFECYCLE_PORTS_INITIALIZED_HOOK || id> TS_LIFECYCLE_LAST_HOOK)
+ return TS_ERROR;
+ return TS_SUCCESS;
+}
TSReturnCode
sdk_sanity_check_null_ptr(void *ptr)
@@ -1241,58 +1247,15 @@ APIHooks::get()
return m_hooks.head;
}
-
-HttpAPIHooks::HttpAPIHooks():
-hooks_set(0)
-{
-}
-
-HttpAPIHooks::~HttpAPIHooks()
-{
- clear();
-}
-
-
-
void
-HttpAPIHooks::clear()
+APIHooks::clear()
{
- APIHook *api_hook;
- APIHook *next_hook;
- int i;
-
- for (i = 0; i < TS_HTTP_LAST_HOOK; i++) {
- api_hook = m_hooks[i].get();
- while (api_hook) {
- next_hook = api_hook->m_link.next;
- apiHookAllocator.free(api_hook);
- api_hook = next_hook;
- }
+ APIHook* hook;
+ while (0 != (hook = m_hooks.pop())) {
+ apiHookAllocator.free(hook);
}
- hooks_set = 0;
}
-void
-HttpAPIHooks::prepend(TSHttpHookID id, INKContInternal *cont)
-{
- hooks_set = 1;
- m_hooks[id].prepend(cont);
-}
-
-void
-HttpAPIHooks::append(TSHttpHookID id, INKContInternal *cont)
-{
- hooks_set = 1;
- m_hooks[id].append(cont);
-}
-
-APIHook *
-HttpAPIHooks::get(TSHttpHookID id)
-{
- return m_hooks[id].get();
-}
-
-
////////////////////////////////////////////////////////////////////
//
// ConfigUpdateCbTable
@@ -1616,6 +1579,7 @@ api_init()
TS_HTTP_LEN_S_MAXAGE = HTTP_LEN_S_MAXAGE;
http_global_hooks = NEW(new HttpAPIHooks);
+ lifecycle_hooks = NEW(new LifecycleAPIHooks);
global_config_cbs = NEW(new ConfigUpdateCbTable);
if (TS_MAX_API_STATS > 0) {
@@ -4416,6 +4380,15 @@ TSHttpHookAdd(TSHttpHookID id, TSCont contp)
}
void
+TSLifecycleHookAdd(TSLifecycleHookID id, TSCont contp)
+{
+ sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS);
+ sdk_assert(sdk_sanity_check_lifecycle_hook_id(id) == TS_SUCCESS);
+
+ lifecycle_hooks->append(id, (INKContInternal *)contp);
+}
+
+void
TSHttpIcpDynamicSet(int value)
{
int32_t old_value, new_value;
@@ -8193,5 +8166,3 @@ TSHttpTxnBackgroundFillStarted(TSHttpTxn txnp)
return (s->background_fill == BACKGROUND_FILL_STARTED);
}
-
-#endif //TS_NO_API
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/InkAPIInternal.h
----------------------------------------------------------------------
diff --git a/proxy/InkAPIInternal.h b/proxy/InkAPIInternal.h
index 4aabd1b..f40af8e 100644
--- a/proxy/InkAPIInternal.h
+++ b/proxy/InkAPIInternal.h
@@ -133,36 +133,100 @@ public:
LINK(APIHook, m_link);
};
-
class APIHooks
{
public:
void prepend(INKContInternal * cont);
void append(INKContInternal * cont);
APIHook *get();
+ void clear();
private:
Que(APIHook, m_link) m_hooks;
};
-
-class HttpAPIHooks
+/** Container for API hooks for a specific feature.
+ */
+template <
+ typename ID, ///< Type of hook ID
+ ID MAX_ID ///< Maximum value for ID
+>
+class FeatureAPIHooks
{
public:
- HttpAPIHooks();
- ~HttpAPIHooks();
+ FeatureAPIHooks();
+ ~FeatureAPIHooks();
void clear();
- void prepend(TSHttpHookID id, INKContInternal * cont);
- void append(TSHttpHookID id, INKContInternal * cont);
- APIHook *get(TSHttpHookID id);
+ void prepend(ID id, INKContInternal * cont);
+ void append(ID id, INKContInternal * cont);
+ APIHook *get(ID id);
- // A boolean value to quickly see if
- // any hooks are set
- int hooks_set;
+ bool has_hooks() const;
private:
- APIHooks m_hooks[TS_HTTP_LAST_HOOK];
+ bool hooks_p; ///< Enable fast check for any hooks.
+ APIHooks m_hooks[MAX_ID];
+};
+
+template < typename ID, ID MAX_ID >
+FeatureAPIHooks<ID,MAX_ID>::FeatureAPIHooks():
+hooks_p(false)
+{
+}
+
+template < typename ID, ID MAX_ID >
+FeatureAPIHooks<ID,MAX_ID>::~FeatureAPIHooks()
+{
+ this->clear();
+}
+
+template < typename ID, ID MAX_ID >
+void
+FeatureAPIHooks<ID,MAX_ID>::clear()
+{
+ for (int i = 0; i < MAX_ID; ++i) {
+ m_hooks->clear();
+ }
+ hooks_p = false;
+}
+
+template < typename ID, ID MAX_ID >
+void
+FeatureAPIHooks<ID,MAX_ID>::prepend(ID id, INKContInternal *cont)
+{
+ hooks_p = true;
+ m_hooks[id].prepend(cont);
+}
+
+template < typename ID, ID MAX_ID >
+void
+FeatureAPIHooks<ID,MAX_ID>::append(ID id, INKContInternal *cont)
+{
+ hooks_p = true;
+ m_hooks[id].append(cont);
+}
+
+template < typename ID, ID MAX_ID >
+APIHook *
+FeatureAPIHooks<ID,MAX_ID>::get(ID id)
+{
+ return m_hooks[id].get();
+}
+
+template < typename ID, ID MAX_ID >
+bool
+FeatureAPIHooks<ID,MAX_ID>::has_hooks() const
+{
+ return hooks_p;
+}
+
+class HttpAPIHooks : public FeatureAPIHooks<TSHttpHookID, TS_HTTP_LAST_HOOK>
+{
+};
+
+class LifecycleAPIHooks : public FeatureAPIHooks<TSLifecycleHookID, TS_LIFECYCLE_LAST_HOOK>
+{
};
@@ -214,6 +278,7 @@ private:
void api_init();
extern HttpAPIHooks *http_global_hooks;
+extern LifecycleAPIHooks* lifecycle_hooks;
extern ConfigUpdateCbTable *global_config_cbs;
#endif /* __INK_API_INTERNAL_H__ */
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/Main.cc
----------------------------------------------------------------------
diff --git a/proxy/Main.cc b/proxy/Main.cc
index 9e9b4db..10804cd 100644
--- a/proxy/Main.cc
+++ b/proxy/Main.cc
@@ -159,7 +159,12 @@ static inkcoreapi DiagsConfig *diagsConfig = NULL;
HttpBodyFactory *body_factory = NULL;
static int accept_mss = 0;
-static int cmd_line_dprintf_level = 0; // default debug output level fro ink_dprintf function
+static int cmd_line_dprintf_level = 0; // default debug output level from ink_dprintf function
+
+// 1: delay listen, wait for cache.
+// 0: Do not delay, start listen ASAP.
+// -1: cache is already initialized, don't delay.
+static volatile int delay_listen_for_cache_p = 0;
AppVersionInfo appVersionInfo; // Build info for this application
@@ -435,6 +440,26 @@ skip(char *cmd, int null_ok = 0)
return cmd;
}
+// Handler for things that need to wait until the cache is initialized.
+static void
+CB_After_Cache_Init()
+{
+ APIHook* hook;
+ int start;
+
+ start = ink_atomic_swap(&delay_listen_for_cache_p, -1);
+ if (1 == start) {
+ Debug("http_listen", "Delayed listen enable, cache initialization finished");
+ start_HttpProxyServer();
+ }
+ // Alert the plugins the cache is initialized.
+ hook = lifecycle_hooks->get(TS_LIFECYCLE_CACHE_READY_HOOK);
+ while (hook) {
+ hook->invoke(TS_EVENT_LIFECYCLE_CACHE_READY, NULL);
+ hook = hook->next();
+ }
+}
+
struct CmdCacheCont: public Continuation
{
@@ -485,7 +510,7 @@ struct CmdCacheCont: public Continuation
return EVENT_CONT;
}
-CmdCacheCont(bool check, bool fix = false):Continuation(new_ProxyMutex()) {
+ CmdCacheCont(bool check, bool fix = false):Continuation(new_ProxyMutex()) {
cache_fix = fix;
if (check)
SET_HANDLER(&CmdCacheCont::CheckEvent);
@@ -551,7 +576,6 @@ cmd_repair(char *cmd)
}
#endif
-
static int
cmd_clear(char *cmd)
{
@@ -1555,6 +1579,7 @@ main(int /* argc ATS_UNUSED */, char **argv)
HttpProxyPort::loadConfig();
HttpProxyPort::loadDefaultIfEmpty();
+ cacheProcessor.set_after_init_callback(&CB_After_Cache_Init);
cacheProcessor.start();
// UDP net-threads are turned off by default.
@@ -1601,11 +1626,13 @@ main(int /* argc ATS_UNUSED */, char **argv)
// main server logic initiated here //
//////////////////////////////////////
-#ifndef TS_NO_TRANSFORM
+ plugin_init(system_config_directory); // plugin.config
+ pmgmt->registerPluginCallbacks(global_config_cbs);
+
transformProcessor.start();
-#endif
- init_HttpProxyServer();
+ init_HttpProxyServer(num_accept_threads);
+
int http_enabled = 1;
TS_ReadConfigInteger(http_enabled, "proxy.config.http.enabled");
@@ -1614,21 +1641,29 @@ main(int /* argc ATS_UNUSED */, char **argv)
int icp_enabled = 0;
TS_ReadConfigInteger(icp_enabled, "proxy.config.icp.enabled");
#endif
- start_HttpProxyServer(num_accept_threads);
+ // call the ready hooks before we start accepting connections.
+ APIHook* hook = lifecycle_hooks->get(TS_LIFECYCLE_PORTS_INITIALIZED_HOOK);
+ while (hook) {
+ hook->invoke(TS_EVENT_LIFECYCLE_PORTS_INITIALIZED, NULL);
+ hook = hook->next();
+ }
+
+ int delay_p = 0;
+ TS_ReadConfigInteger(delay_p, "proxy.config.http.wait_for_cache");
+
+ // Delay only if config value set and flag value is zero
+ // (-1 => cache already initialized)
+ if (delay_p && ink_atomic_cas(&delay_listen_for_cache_p, 0, 1)) {
+ Debug("http_listen", "Delaying listen, waiting for cache initialization");
+ } else {
+ start_HttpProxyServer(); // PORTS_READY_HOOK called from in here
+ }
#ifndef INK_NO_ICP
if (icp_enabled)
icpProcessor.start();
#endif
}
-#ifdef TS_NO_API
- api_init(); // we still need to initialize some of the data structure other module needs.
- // i.e. http_global_hooks
-#else
- plugin_init(system_config_directory); // plugin.config
- pmgmt->registerPluginCallbacks(global_config_cbs);
-#endif
-
// "Task" processor, possibly with its own set of task threads
tasksProcessor.start(num_task_threads, stacksize);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/Transform.cc
----------------------------------------------------------------------
diff --git a/proxy/Transform.cc b/proxy/Transform.cc
index eb5cfe4..2da3301 100644
--- a/proxy/Transform.cc
+++ b/proxy/Transform.cc
@@ -59,8 +59,6 @@
*/
-#ifndef TS_NO_TRANSFORM
-
#include "ProxyConfig.h"
#include "P_Net.h"
#include "MimeTable.h"
@@ -1040,5 +1038,3 @@ RangeTransform::change_response_header()
}
#undef RANGE_NUMBERS_LENGTH
-
-#endif // TS_NO_TRANSFORM
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/api/ts/ts.h.in
----------------------------------------------------------------------
diff --git a/proxy/api/ts/ts.h.in b/proxy/api/ts/ts.h.in
index 5ba4ebe..fc65e0e 100644
--- a/proxy/api/ts/ts.h.in
+++ b/proxy/api/ts/ts.h.in
@@ -276,6 +276,55 @@ extern "C"
} TSHttpHookID;
#define TS_HTTP_READ_REQUEST_PRE_REMAP_HOOK TS_HTTP_PRE_REMAP_HOOK /* backwards compat */
+ /** Plugin lifecycle hooks.
+
+ These are called during lifecycle events of a plugin. They
+ should be set in the plugin initialization function. The
+ continuation is invoked with an event ID specified for each hook
+ and @c NULL for the event data.
+
+ TS_LIFECYCLE_PORTS_INITIALIZED_HOOK
+
+ called once, after the HTTP proxy port data structures have
+ been initialized. In particular, SSL related calls that depend
+ on accept endpoints may be invoked. After this hook is
+ finished, the proxy port sockets are opened and connections
+ are accepted.
+
+ Event: TS_EVENT_LIFECYCLE_PORTS_INITIALIZED
+
+ TS_LIFECYCLE_PORTS_READY_HOOK
+
+ called once, after the sockets have been opened and the accept
+ threads have been started. That is, the ports are ready to
+ accept connections. This is *not* guaranteed to be called
+ before the first connection is accepted.
+
+ Event: TS_EVENT_LIFECYCLE_PORTS_READY_HOOK
+
+ TS_LIFECYCLE_CACHE_READY_HOOK
+
+ called once, after the cache has finished its
+ initialization. It is either online or has failed when this
+ hook is called.
+
+ Event: TS_EVENT_LIFECYCLE_CACHE_READY
+
+ Ordering guarantees:
+
+ - TS_LIFECYCLE_PORTS_INITIALIZED_HOOK before TS_LIFECYCLE_PORTS_READY_HOOK.
+
+ NOTE! ONLY the orderings EXPLICITLY mentioned above are guaranteed.
+
+ */
+ typedef enum
+ {
+ TS_LIFECYCLE_PORTS_INITIALIZED_HOOK,
+ TS_LIFECYCLE_PORTS_READY_HOOK,
+ TS_LIFECYCLE_CACHE_READY_HOOK,
+ TS_LIFECYCLE_LAST_HOOK
+ } TSLifecycleHookID;
+
/**
TSEvents are sent to continuations when they are called back.
The TSEvent provides the continuation's handler function with
@@ -361,6 +410,9 @@ extern "C"
TS_EVENT_HTTP_CACHE_LOOKUP_COMPLETE = 60015,
TS_EVENT_HTTP_PRE_REMAP = 60016,
TS_EVENT_HTTP_POST_REMAP = 60017,
+ TS_EVENT_LIFECYCLE_PORTS_INITIALIZED = 60018,
+ TS_EVENT_LIFECYCLE_PORTS_READY = 60019,
+ TS_EVENT_LIFECYCLE_CACHE_READY = 60020,
TS_EVENT_MGMT_UPDATE = 60100,
/* EVENTS 60200 - 60202 for internal use */
@@ -2191,6 +2243,9 @@ extern "C"
tsapi TSMutex TSContMutexGet(TSCont contp);
/* --------------------------------------------------------------------------
+ Plugin lifecycle hooks */
+ tsapi void TSLifecycleHookAdd(TSLifecycleHookID id, TSCont contp);
+ /* --------------------------------------------------------------------------
HTTP hooks */
tsapi void TSHttpHookAdd(TSHttpHookID id, TSCont contp);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpClientSession.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpClientSession.cc b/proxy/http/HttpClientSession.cc
index 21cc5ea..2601242 100644
--- a/proxy/http/HttpClientSession.cc
+++ b/proxy/http/HttpClientSession.cc
@@ -225,7 +225,7 @@ HttpClientSession::new_connection(NetVConnection * new_vc, bool backdoor)
}
// Record api hook set state
- hooks_set = http_global_hooks->hooks_set;
+ hooks_set = http_global_hooks->has_hooks();
#ifdef USE_HTTP_DEBUG_LISTS
ink_mutex_acquire(&debug_cs_list_mutex);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpProxyServerMain.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpProxyServerMain.cc b/proxy/http/HttpProxyServerMain.cc
index 007fb90..485ce96 100644
--- a/proxy/http/HttpProxyServerMain.cc
+++ b/proxy/http/HttpProxyServerMain.cc
@@ -39,7 +39,6 @@
HttpAccept *plugin_http_accept = NULL;
HttpAccept *plugin_http_transparent_accept = 0;
-#if !defined(TS_NO_API)
static SLL<SSLNextProtocolAccept> ssl_plugin_acceptors;
static ProcessMutex ssl_plugin_mutex;
@@ -73,47 +72,43 @@ ssl_unregister_protocol(const char * protocol, Continuation * contp)
return true;
}
-#endif /* !defined(TS_NO_API) */
-
/////////////////////////////////////////////////////////////////
//
// main()
//
/////////////////////////////////////////////////////////////////
-void
-init_HttpProxyServer(void)
-{
-#ifndef INK_NO_REVERSE
- init_reverse_proxy();
-#endif
-// HttpConfig::startup();
- httpSessionManager.init();
- http_pages_init();
- ink_mutex_init(&debug_sm_list_mutex, "HttpSM Debug List");
- ink_mutex_init(&debug_cs_list_mutex, "HttpCS Debug List");
- // DI's request to disable/reenable ICP on the fly
- icp_dynamic_enabled = 1;
-#ifndef TS_NO_API
- // Used to give plugins the ability to create http requests
- // The equivalent of the connecting to localhost on the proxy
- // port but without going through the operating system
- //
- if (plugin_http_accept == NULL) {
- plugin_http_accept = NEW(new HttpAccept);
- plugin_http_accept->mutex = new_ProxyMutex();
- }
- // Same as plugin_http_accept except outbound transparent.
- if (! plugin_http_transparent_accept) {
- HttpAccept::Options ha_opt;
- ha_opt.setOutboundTransparent(true);
- plugin_http_transparent_accept = NEW(new HttpAccept(ha_opt));
- plugin_http_transparent_accept->mutex = new_ProxyMutex();
- }
- ink_mutex_init(&ssl_plugin_mutex, "SSL Acceptor List");
-#endif
-}
+/** Data about an acceptor.
+
+ This is used to separate setting up the proxy ports and
+ starting to accept on them.
+
+*/
+struct HttpProxyAcceptor {
+ /// Accept continuation.
+ Continuation* _accept;
+ /// Options for @c NetProcessor.
+ NetProcessor::AcceptOptions _net_opt;
+
+ /// Default constructor.
+ HttpProxyAcceptor()
+ : _accept(0)
+ {
+ }
+};
+/** Global acceptors.
+
+ This is parallel to @c HttpProxyPort::global(), each generated
+ from the corresponding port descriptor.
+
+ @internal We use @c Continuation instead of @c HttpAccept because
+ @c SSLNextProtocolAccept is a subclass of @c Cont instead of @c
+ HttpAccept.
+*/
+Vec<HttpProxyAcceptor> HttpProxyAcceptors;
+
+// Called from InkAPI.cc
NetProcessor::AcceptOptions
make_net_accept_options(const HttpProxyPort& port, unsigned nthreads)
{
@@ -136,67 +131,116 @@ make_net_accept_options(const HttpProxyPort& port, unsigned nthreads)
return net;
}
-static bool
-start_HttpProxyPort(const HttpProxyPort& port, unsigned nthreads)
+static void
+MakeHttpProxyAcceptor(HttpProxyAcceptor& acceptor, HttpProxyPort& port, unsigned nthreads)
{
- NetProcessor::AcceptOptions net(make_net_accept_options(port, nthreads));
- HttpAccept::Options http;
+ NetProcessor::AcceptOptions& net_opt = acceptor._net_opt;
+ HttpAccept::Options accept_opt;
- REC_ReadConfigInteger(net.recv_bufsize, "proxy.config.net.sock_recv_buffer_size_in");
- REC_ReadConfigInteger(net.send_bufsize, "proxy.config.net.sock_send_buffer_size_in");
- REC_ReadConfigInteger(net.packet_mark, "proxy.config.net.sock_packet_mark_in");
- REC_ReadConfigInteger(net.packet_tos, "proxy.config.net.sock_packet_tos_in");
+ net_opt = make_net_accept_options(port, nthreads);
+ REC_ReadConfigInteger(net_opt.recv_bufsize, "proxy.config.net.sock_recv_buffer_size_in");
+ REC_ReadConfigInteger(net_opt.send_bufsize, "proxy.config.net.sock_send_buffer_size_in");
+ REC_ReadConfigInteger(net_opt.packet_mark, "proxy.config.net.sock_packet_mark_in");
+ REC_ReadConfigInteger(net_opt.packet_tos, "proxy.config.net.sock_packet_tos_in");
- http.f_outbound_transparent = port.m_outbound_transparent_p;
- http.transport_type = port.m_type;
- http.setHostResPreference(port.m_host_res_preference);
- http.setTransparentPassthrough(port.m_transparent_passthrough);
+ accept_opt.f_outbound_transparent = port.m_outbound_transparent_p;
+ accept_opt.transport_type = port.m_type;
+ accept_opt.setHostResPreference(port.m_host_res_preference);
+ accept_opt.setTransparentPassthrough(port.m_transparent_passthrough);
if (port.m_outbound_ip4.isValid()) {
- http.outbound_ip4 = port.m_outbound_ip4;
+ accept_opt.outbound_ip4 = port.m_outbound_ip4;
} else if (HttpConfig::m_master.outbound_ip4.isValid()) {
- http.outbound_ip4 = HttpConfig::m_master.outbound_ip4;
+ accept_opt.outbound_ip4 = HttpConfig::m_master.outbound_ip4;
}
if (port.m_outbound_ip6.isValid()) {
- http.outbound_ip6 = port.m_outbound_ip6;
+ accept_opt.outbound_ip6 = port.m_outbound_ip6;
} else if (HttpConfig::m_master.outbound_ip6.isValid()) {
- http.outbound_ip6 = HttpConfig::m_master.outbound_ip6;
+ accept_opt.outbound_ip6 = HttpConfig::m_master.outbound_ip6;
}
if (port.isSSL()) {
- HttpAccept * accept = NEW(new HttpAccept(http));
+ HttpAccept * accept = NEW(new HttpAccept(accept_opt));
SSLNextProtocolAccept * ssl = NEW(new SSLNextProtocolAccept(accept));
ssl->registerEndpoint(TS_NPN_PROTOCOL_HTTP_1_0, accept);
ssl->registerEndpoint(TS_NPN_PROTOCOL_HTTP_1_1, accept);
-#ifndef TS_NO_API
ink_scoped_mutex lock(ssl_plugin_mutex);
ssl_plugin_acceptors.push(ssl);
-#endif
- return sslNetProcessor.main_accept(ssl, port.m_fd, net) != NULL;
+ acceptor._accept = ssl;
} else {
- return netProcessor.main_accept(NEW(new HttpAccept(http)), port.m_fd, net) != NULL;
+ acceptor._accept = NEW(new HttpAccept(accept_opt));
+ }
+}
+
+/** Set up all the accepts and sockets.
+ */
+void
+init_HttpProxyServer(int n_accept_threads)
+{
+ HttpProxyPort::Group& proxy_ports = HttpProxyPort::global();
+
+#ifndef INK_NO_REVERSE
+ init_reverse_proxy();
+#endif
+ httpSessionManager.init();
+ http_pages_init();
+ ink_mutex_init(&debug_sm_list_mutex, "HttpSM Debug List");
+ ink_mutex_init(&debug_cs_list_mutex, "HttpCS Debug List");
+ // DI's request to disable/reenable ICP on the fly
+ icp_dynamic_enabled = 1;
+
+ // Used to give plugins the ability to create http requests
+ // The equivalent of the connecting to localhost on the proxy
+ // port but without going through the operating system
+ //
+ if (plugin_http_accept == NULL) {
+ plugin_http_accept = NEW(new HttpAccept);
+ plugin_http_accept->mutex = new_ProxyMutex();
}
+ // Same as plugin_http_accept except outbound transparent.
+ if (! plugin_http_transparent_accept) {
+ HttpAccept::Options ha_opt;
+ ha_opt.setOutboundTransparent(true);
+ plugin_http_transparent_accept = NEW(new HttpAccept(ha_opt));
+ plugin_http_transparent_accept->mutex = new_ProxyMutex();
+ }
+ ink_mutex_init(&ssl_plugin_mutex, "SSL Acceptor List");
- // XXX although we make a good pretence here, I don't believe that NetProcessor::main_accept() ever actually returns
- // NULL. It would be useful to be able to detect errors and spew them here though.
+ // Do the configuration defined ports.
+ for ( int i = 0 , n = proxy_ports.length() ; i < n ; ++i ) {
+ MakeHttpProxyAcceptor(HttpProxyAcceptors.add(), proxy_ports[i], n_accept_threads);
+ }
+
}
void
-start_HttpProxyServer(int accept_threads)
+start_HttpProxyServer()
{
static bool called_once = false;
+ HttpProxyPort::Group& proxy_ports = HttpProxyPort::global();
///////////////////////////////////
// start accepting connections //
///////////////////////////////////
ink_assert(!called_once);
-
- for ( int i = 0 , n = HttpProxyPort::global().length() ; i < n ; ++i ) {
- start_HttpProxyPort(HttpProxyPort::global()[i], accept_threads);
+ ink_assert(proxy_ports.length() == HttpProxyAcceptors.length());
+
+ for ( int i = 0 , n = proxy_ports.length() ; i < n ; ++i ) {
+ HttpProxyAcceptor& acceptor = HttpProxyAcceptors[i];
+ HttpProxyPort& port = proxy_ports[i];
+ if (port.isSSL()) {
+ if (NULL == sslNetProcessor.main_accept(acceptor._accept, port.m_fd, acceptor._net_opt))
+ return;
+ } else {
+ if (NULL == netProcessor.main_accept(acceptor._accept, port.m_fd, acceptor._net_opt))
+ return;
+ }
+ // XXX although we make a good pretence here, I don't believe that NetProcessor::main_accept() ever actually returns
+ // NULL. It would be useful to be able to detect errors and spew them here though.
}
#if TS_HAS_TESTS
@@ -204,6 +248,14 @@ start_HttpProxyServer(int accept_threads)
init_http_update_test();
}
#endif
+
+ // Alert plugins that connections will be accepted.
+ APIHook* hook = lifecycle_hooks->get(TS_LIFECYCLE_PORTS_READY_HOOK);
+ while (hook) {
+ hook->invoke(TS_EVENT_LIFECYCLE_PORTS_READY, NULL);
+ hook = hook->next();
+ }
+
}
void
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpProxyServerMain.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpProxyServerMain.h b/proxy/http/HttpProxyServerMain.h
index 1d0502e..98769ff 100644
--- a/proxy/http/HttpProxyServerMain.h
+++ b/proxy/http/HttpProxyServerMain.h
@@ -23,12 +23,14 @@
struct HttpProxyPort;
-void init_HttpProxyServer(void);
+/** Initialize all HTTP proxy port data structures needed to run.
+ */
+void init_HttpProxyServer(int n_accept_threads = 0);
/** Start the proxy server.
- The ports are contained in the HttpProxyPort global data.
+ The port data should have been created by @c init_HttpProxyServer().
*/
-void start_HttpProxyServer(int accept_threads = 0);
+void start_HttpProxyServer();
void start_HttpProxyServerBackDoor(int port, int accept_threads = 0);
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 1ebf842..4cfe0d1 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -612,7 +612,7 @@ HttpSM::attach_client_session(HttpClientSession * client_vc, IOBufferReader * bu
HTTP_INCREMENT_DYN_STAT(http_current_client_transactions_stat);
// Record api hook set state
- hooks_set = http_global_hooks->hooks_set | client_vc->hooks_set;
+ hooks_set = http_global_hooks->has_hooks() || client_vc->hooks_set;
// Setup for parsing the header
ua_buffer_reader = buffer_reader;
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpTransact.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
index 820663a..c8cc90f 100644
--- a/proxy/http/HttpTransact.cc
+++ b/proxy/http/HttpTransact.cc
@@ -4617,7 +4617,6 @@ HttpTransact::handle_transform_ready(State* s)
void
HttpTransact::set_header_for_transform(State* s, HTTPHdr* base_header)
{
-#ifndef TS_NO_TRANSFORM
s->hdr_info.transform_response.create(HTTP_TYPE_RESPONSE);
s->hdr_info.transform_response.copy(base_header);
@@ -4628,9 +4627,6 @@ HttpTransact::set_header_for_transform(State* s, HTTPHdr* base_header)
if (!s->cop_test_page)
DUMP_HEADER("http_hdrs", &s->hdr_info.transform_response, s->state_machine_id, "Header To Transform");
-#else
- ink_assert(!"transformation not supported\n");
-#endif // TS_NO_TRANSFORM
}
void
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpUpdateSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpUpdateSM.cc b/proxy/http/HttpUpdateSM.cc
index 7b5eddf..6b47881 100644
--- a/proxy/http/HttpUpdateSM.cc
+++ b/proxy/http/HttpUpdateSM.cc
@@ -116,7 +116,6 @@ HttpUpdateSM::handle_api_return()
}
switch (t_state.next_action) {
-#ifndef TS_NO_TRANSFORM
case HttpTransact::TRANSFORM_READ:
{
if (t_state.cache_info.transform_action == HttpTransact::CACHE_DO_WRITE) {
@@ -154,7 +153,6 @@ HttpUpdateSM::handle_api_return()
}
break;
}
-#endif //TS_NO_TRANSFORM
case HttpTransact::PROXY_INTERNAL_CACHE_WRITE:
case HttpTransact::SERVER_READ:
case HttpTransact::PROXY_INTERNAL_CACHE_NOOP:
Re: git commit: TS-1487: Fix startup order, add lifecycle hooks
Posted by "Alan M. Carroll" <am...@network-geographics.com>.
Friday, July 19, 2013, 5:49:33 AM, you wrote:
>> Changes with Apache Traffic Server 3.3.5
>>
>> + *) [TS-1487] [TS-2035] Moved plugin init, added plugin lifecycle
>> hooks, added delay listen for cache. Removed TS_NO_API defined/build
>> option.
>> +
> Why are those three changes all munged into one commit?
Because TS-2035 is a duplicate of TS-1487 and the rest of that is part of the proposed fix for TS-1487. The TS_NO_API is in there because it was getting in my way while I was fixing this and I solved it zwoop-style.
Re: git commit: TS-1487: Fix startup order, add lifecycle hooks
Posted by Igor Galić <i....@brainsware.org>.
----- Original Message -----
> Updated Branches:
> refs/heads/master ea560cecc -> 941784b2a
>
>
> TS-1487: Fix startup order, add lifecycle hooks
vs
> ----------------------------------------------------------------------
> diff --git a/CHANGES b/CHANGES
> index 599f7bf..d6889d8 100644
> --- a/CHANGES
> +++ b/CHANGES
> @@ -1,6 +1,8 @@
> -*- coding:
> utf-8 -*-
> Changes with Apache Traffic Server 3.3.5
>
> + *) [TS-1487] [TS-2035] Moved plugin init, added plugin lifecycle
> hooks, added delay listen for cache. Removed TS_NO_API defined/build
> option.
> +
Why are those three changes all munged into one commit?
> *) [TS-2047] Schedule RamCacheCLFUSCompressor in
> RamCacheCLFUS::init instead
> of immediatly after instantiation.
>
>
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/configure.ac
> ----------------------------------------------------------------------
> diff --git a/configure.ac b/configure.ac
> index 0bc7a00..0d2285a 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -279,19 +279,6 @@ AC_MSG_RESULT([$enable_remote_cov_commit])
> AC_SUBST([enable_remote_cov_commit])
>
> #
> -# API
> -#
> -AC_MSG_CHECKING([whether to enable API and plugin support])
> -AC_ARG_ENABLE([api],
> - [AS_HELP_STRING([--disable-api],[do not enable API and plugin
> support])],
> - [],
> - [enable_api=yes]
> -)
> -AC_MSG_RESULT([$enable_api])
> -AS_IF([test "x$enable_api" = "xyes"], [has_inkapi=1],
> [has_inkapi=0])
> -AC_SUBST(has_inkapi)
> -
> -#
> # WCCP
> #
> AC_MSG_CHECKING([whether to enable WCCP v2 support])
>
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/example/Makefile.am
> ----------------------------------------------------------------------
> diff --git a/example/Makefile.am b/example/Makefile.am
> index e0939e0..193e1c4 100644
> --- a/example/Makefile.am
> +++ b/example/Makefile.am
> @@ -28,6 +28,7 @@ noinst_LTLIBRARIES = \
> cache-scan.la \
> file-1.la \
> hello.la \
> + lifecycle-plugin.la \
tab vs spaces
> null-transform.la \
> output-header.la \
> protocol.la \
> @@ -48,6 +49,7 @@ bnull_transform_la_SOURCES =
> bnull-transform/bnull-transform.c
> cache_scan_la_SOURCES = cache-scan/cache-scan.cc
> file_1_la_SOURCES = file-1/file-1.c
> hello_la_SOURCES = hello/hello.c
> +lifecycle_plugin_la_SOURCES = lifecycle-plugin/lifecycle-plugin.c
> null_transform_la_SOURCES = null-transform/null-transform.c
> output_header_la_SOURCES = output-header/output-header.c
> protocol_la_SOURCES = protocol/Protocol.c protocol/TxnSM.c
>
[snip]
> ----------------------------------------------------------------------
> diff --git a/example/lifecycle-plugin/lifecycle-plugin.c
> b/example/lifecycle-plugin/lifecycle-plugin.c
> new file mode 100644
> index 0000000..e08fbc3
> --- /dev/null
> +++ b/example/lifecycle-plugin/lifecycle-plugin.c
[snip]
> +int
> +CheckVersion()
> +{
> + const char *ts_version = TSTrafficServerVersionGet();
> + int result = 0;
> +
> + if (ts_version) {
> + int major_ts_version = 0;
> + int minor_ts_version = 0;
> + int patch_ts_version = 0;
> +
> + if (sscanf(ts_version, "%d.%d.%d", &major_ts_version,
> &minor_ts_version, &patch_ts_version) != 3) {
> + return 0;
> + }
> +
> + /* Need at least TS 3.3.5 */
> + if (major_ts_version > 3 ||
> + (major_ts_version == 3 &&
> + (minor_ts_version > 3 ||
> + (minor_ts_version == 3 && patch_ts_version >= 5)))) {
> + result = 1;
> + }
> + }
> + return result;
> +}
another reminder of https://issues.apache.org/jira/browse/TS-1953
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/mgmt/RecordsConfig.cc
> ----------------------------------------------------------------------
> diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
> index f0cc3c8..66102f4 100644
> --- a/mgmt/RecordsConfig.cc
> +++ b/mgmt/RecordsConfig.cc
> @@ -390,6 +390,8 @@ RecordElement RecordsConfig[] = {
> ,
> {RECT_CONFIG, "proxy.config.http.server_other_ports", RECD_STRING,
> NULL, RECU_RESTART_TM, RR_NULL, RECC_NULL, NULL, RECA_NULL}
> ,
> + {RECT_CONFIG, "proxy.config.http.wait_for_cache", RECD_INT, "1",
> RECU_RESTART_TM, RR_NULL, RECC_INT, "[0-1]", RECA_NULL}
> + ,
maybe in CHANGES we should write what the consequence of that change
was rather than writing that we've made some change to fix TS-blah-blah
> {RECT_CONFIG, "proxy.config.http.insert_request_via_str",
> RECD_INT, "1", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL}
> ,
> {RECT_CONFIG, "proxy.config.http.insert_response_via_str",
> RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL}
>
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/IPAllow.h
> ----------------------------------------------------------------------
> diff --git a/proxy/IPAllow.h b/proxy/IPAllow.h
> index 941a7e7..76ecdf4 100644
> --- a/proxy/IPAllow.h
> +++ b/proxy/IPAllow.h
> @@ -34,7 +34,6 @@
> #include "Main.h"
> #include "hdrs/HTTP.h"
> #include "ts/IpMap.h"
> -#include "vector"
> #include "ts/Vec.h"
> #include "ProxyConfig.h"
This seems to be part of an unrelated(?) clean-up change.
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/InkAPI.cc
> ----------------------------------------------------------------------
> diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
> index cabab42..540bec8 100644
> --- a/proxy/InkAPI.cc
> +++ b/proxy/InkAPI.cc
> @@ -21,8 +21,6 @@
> limitations under the License.
> */
>
> -#ifndef TS_NO_API
> -
> // Avoid complaining about the deprecated APIs.
> // #define TS_DEPRECATED
>
> @@ -369,6 +367,7 @@ tsapi const char * TS_NPN_PROTOCOL_SPDY_3 =
> "spdy/3"; // upcoming
> tsapi const TSMLoc TS_NULL_MLOC = (TSMLoc)NULL;
>
> HttpAPIHooks *http_global_hooks = NULL;
> +LifecycleAPIHooks* lifecycle_hooks = NULL;
> ConfigUpdateCbTable *global_config_cbs = NULL;
>
> static char traffic_server_version[128] = "";
> @@ -630,6 +629,13 @@ sdk_sanity_check_hook_id(TSHttpHookID id)
> return TS_SUCCESS;
> }
>
> +TSReturnCode
> +sdk_sanity_check_lifecycle_hook_id(TSLifecycleHookID id)
> +{
> + if (id<TS_LIFECYCLE_PORTS_INITIALIZED_HOOK || id> TS_LIFECYCLE_LAST_HOOK)
please try to use consistent spacing for </>, see below:
[wild-snipping]
> +template < typename ID, ID MAX_ID >
> +FeatureAPIHooks<ID,MAX_ID>::FeatureAPIHooks():
> +template < typename ID, ID MAX_ID >
> +FeatureAPIHooks<ID,MAX_ID>::~FeatureAPIHooks()
> +template < typename ID, ID MAX_ID >
> +void
> +FeatureAPIHooks<ID,MAX_ID>::clear()
> +template < typename ID, ID MAX_ID >
> +FeatureAPIHooks<ID,MAX_ID>::prepend(ID id, INKContInternal *cont)
> +template < typename ID, ID MAX_ID >
> +void
> +FeatureAPIHooks<ID,MAX_ID>::append(ID id, INKContInternal *cont)
> +template < typename ID, ID MAX_ID >
> +APIHook *
> +FeatureAPIHooks<ID,MAX_ID>::get(ID id)
> +template < typename ID, ID MAX_ID >
> +bool
> +FeatureAPIHooks<ID,MAX_ID>::has_hooks() const
> +class HttpAPIHooks : public FeatureAPIHooks<TSHttpHookID, TS_HTTP_LAST_HOOK>
> +class LifecycleAPIHooks : public FeatureAPIHooks<TSLifecycleHookID, TS_LIFECYCLE_LAST_HOOK>
[/wild-snipping]
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/api/ts/ts.h.in
> ----------------------------------------------------------------------
> diff --git a/proxy/api/ts/ts.h.in b/proxy/api/ts/ts.h.in
> index 5ba4ebe..fc65e0e 100644
> --- a/proxy/api/ts/ts.h.in
> +++ b/proxy/api/ts/ts.h.in
> @@ -276,6 +276,55 @@ extern "C"
> } TSHttpHookID;
> #define TS_HTTP_READ_REQUEST_PRE_REMAP_HOOK TS_HTTP_PRE_REMAP_HOOK
> /* backwards compat */
>
> + /** Plugin lifecycle hooks.
> +
> + These are called during lifecycle events of a plugin. They
> + should be set in the plugin initialization function. The
> + continuation is invoked with an event ID specified for each
> hook
> + and @c NULL for the event data.
> +
> + TS_LIFECYCLE_PORTS_INITIALIZED_HOOK
> +
> + called once, after the HTTP proxy port data structures have
> + been initialized. In particular, SSL related calls that
> depend
> + on accept endpoints may be invoked. After this hook is
> + finished, the proxy port sockets are opened and connections
> + are accepted.
> +
> + Event: TS_EVENT_LIFECYCLE_PORTS_INITIALIZED
> +
> + TS_LIFECYCLE_PORTS_READY_HOOK
> +
> + called once, after the sockets have been opened and the
> accept
> + threads have been started. That is, the ports are ready to
> + accept connections. This is *not* guaranteed to be called
> + before the first connection is accepted.
> +
> + Event: TS_EVENT_LIFECYCLE_PORTS_READY_HOOK
> +
> + TS_LIFECYCLE_CACHE_READY_HOOK
> +
> + called once, after the cache has finished its
> + initialization. It is either online or has failed when this
> + hook is called.
> +
> + Event: TS_EVENT_LIFECYCLE_CACHE_READY
> +
> + Ordering guarantees:
> +
> + - TS_LIFECYCLE_PORTS_INITIALIZED_HOOK before
> TS_LIFECYCLE_PORTS_READY_HOOK.
> +
> + NOTE! ONLY the orderings EXPLICITLY mentioned above are
> guaranteed.
> +
> + */
> + typedef enum
> + {
> + TS_LIFECYCLE_PORTS_INITIALIZED_HOOK,
> + TS_LIFECYCLE_PORTS_READY_HOOK,
> + TS_LIFECYCLE_CACHE_READY_HOOK,
> + TS_LIFECYCLE_LAST_HOOK
> + } TSLifecycleHookID;
> +
Could you, following jpeach's example add a man page for this API?
[snip]
> --- a/proxy/http/HttpProxyServerMain.cc
> +++ b/proxy/http/HttpProxyServerMain.cc
> @@ -39,7 +39,6 @@
> HttpAccept *plugin_http_accept = NULL;
> HttpAccept *plugin_http_transparent_accept = 0;
>
> -#if !defined(TS_NO_API)
> static SLL<SSLNextProtocolAccept> ssl_plugin_acceptors;
> static ProcessMutex ssl_plugin_mutex;
>
> @@ -73,47 +72,43 @@ ssl_unregister_protocol(const char * protocol,
> Continuation * contp)
> return true;
> }
>
> -#endif /* !defined(TS_NO_API) */
> -
> /////////////////////////////////////////////////////////////////
> //
> // main()
> //
> /////////////////////////////////////////////////////////////////
> -void
> -init_HttpProxyServer(void)
> -{
> -#ifndef INK_NO_REVERSE
> - init_reverse_proxy();
> -#endif
reminder: https://issues.apache.org/jira/browse/TS-819
https://issues.apache.org/jira/browse/TS-1685
[snip]
>
> - // XXX although we make a good pretence here, I don't believe that
> NetProcessor::main_accept() ever actually returns
> - // NULL. It would be useful to be able to detect errors and spew
> them here though.
hah...
> + // Do the configuration defined ports.
> + for ( int i = 0 , n = proxy_ports.length() ; i < n ; ++i ) {
> + MakeHttpProxyAcceptor(HttpProxyAcceptors.add(), proxy_ports[i],
> n_accept_threads);
> + }
> +
> }
>
> void
> -start_HttpProxyServer(int accept_threads)
> +start_HttpProxyServer()
> {
> static bool called_once = false;
> + HttpProxyPort::Group& proxy_ports = HttpProxyPort::global();
>
> ///////////////////////////////////
> // start accepting connections //
> ///////////////////////////////////
>
> ink_assert(!called_once);
> -
> - for ( int i = 0 , n = HttpProxyPort::global().length() ; i < n ;
> ++i ) {
> - start_HttpProxyPort(HttpProxyPort::global()[i], accept_threads);
> + ink_assert(proxy_ports.length() == HttpProxyAcceptors.length());
> +
> + for ( int i = 0 , n = proxy_ports.length() ; i < n ; ++i ) {
> + HttpProxyAcceptor& acceptor = HttpProxyAcceptors[i];
> + HttpProxyPort& port = proxy_ports[i];
> + if (port.isSSL()) {
> + if (NULL == sslNetProcessor.main_accept(acceptor._accept,
> port.m_fd, acceptor._net_opt))
> + return;
> + } else {
> + if (NULL == netProcessor.main_accept(acceptor._accept,
> port.m_fd, acceptor._net_opt))
> + return;
> + }
> + // XXX although we make a good pretence here, I don't believe
> that NetProcessor::main_accept() ever actually returns
> + // NULL. It would be useful to be able to detect errors and spew
> them here though.
oh.. I thought you had that fixed :\
> }
>
> #if TS_HAS_TESTS
> @@ -204,6 +248,14 @@ start_HttpProxyServer(int accept_threads)
> init_http_update_test();
> }
> #endif
> +
> + // Alert plugins that connections will be accepted.
> + APIHook* hook =
> lifecycle_hooks->get(TS_LIFECYCLE_PORTS_READY_HOOK);
> + while (hook) {
> + hook->invoke(TS_EVENT_LIFECYCLE_PORTS_READY, NULL);
> + hook = hook->next();
> + }
> +
> }
>
> void
>
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpProxyServerMain.h
> ----------------------------------------------------------------------
> diff --git a/proxy/http/HttpProxyServerMain.h
> b/proxy/http/HttpProxyServerMain.h
> index 1d0502e..98769ff 100644
> --- a/proxy/http/HttpProxyServerMain.h
> +++ b/proxy/http/HttpProxyServerMain.h
> @@ -23,12 +23,14 @@
>
> struct HttpProxyPort;
>
> -void init_HttpProxyServer(void);
> +/** Initialize all HTTP proxy port data structures needed to run.
> + */
> +void init_HttpProxyServer(int n_accept_threads = 0);
>
> /** Start the proxy server.
> - The ports are contained in the HttpProxyPort global data.
> + The port data should have been created by @c
> init_HttpProxyServer().
> */
> -void start_HttpProxyServer(int accept_threads = 0);
> +void start_HttpProxyServer();
>
> void start_HttpProxyServerBackDoor(int port, int accept_threads =
> 0);
>
>
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpSM.cc
> ----------------------------------------------------------------------
> diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
> index 1ebf842..4cfe0d1 100644
> --- a/proxy/http/HttpSM.cc
> +++ b/proxy/http/HttpSM.cc
> @@ -612,7 +612,7 @@ HttpSM::attach_client_session(HttpClientSession *
> client_vc, IOBufferReader * bu
> HTTP_INCREMENT_DYN_STAT(http_current_client_transactions_stat);
>
> // Record api hook set state
> - hooks_set = http_global_hooks->hooks_set | client_vc->hooks_set;
> + hooks_set = http_global_hooks->has_hooks() ||
> client_vc->hooks_set;
>
> // Setup for parsing the header
> ua_buffer_reader = buffer_reader;
>
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpTransact.cc
> ----------------------------------------------------------------------
> diff --git a/proxy/http/HttpTransact.cc b/proxy/http/HttpTransact.cc
> index 820663a..c8cc90f 100644
> --- a/proxy/http/HttpTransact.cc
> +++ b/proxy/http/HttpTransact.cc
> @@ -4617,7 +4617,6 @@ HttpTransact::handle_transform_ready(State* s)
> void
> HttpTransact::set_header_for_transform(State* s, HTTPHdr*
> base_header)
> {
> -#ifndef TS_NO_TRANSFORM
> s->hdr_info.transform_response.create(HTTP_TYPE_RESPONSE);
> s->hdr_info.transform_response.copy(base_header);
>
> @@ -4628,9 +4627,6 @@ HttpTransact::set_header_for_transform(State*
> s, HTTPHdr* base_header)
>
> if (!s->cop_test_page)
> DUMP_HEADER("http_hdrs", &s->hdr_info.transform_response,
> s->state_machine_id, "Header To Transform");
> -#else
> - ink_assert(!"transformation not supported\n");
> -#endif // TS_NO_TRANSFORM
> }
>
> void
>
> http://git-wip-us.apache.org/repos/asf/trafficserver/blob/941784b2/proxy/http/HttpUpdateSM.cc
> ----------------------------------------------------------------------
> diff --git a/proxy/http/HttpUpdateSM.cc b/proxy/http/HttpUpdateSM.cc
> index 7b5eddf..6b47881 100644
> --- a/proxy/http/HttpUpdateSM.cc
> +++ b/proxy/http/HttpUpdateSM.cc
> @@ -116,7 +116,6 @@ HttpUpdateSM::handle_api_return()
> }
>
> switch (t_state.next_action) {
> -#ifndef TS_NO_TRANSFORM
> case HttpTransact::TRANSFORM_READ:
> {
> if (t_state.cache_info.transform_action ==
> HttpTransact::CACHE_DO_WRITE) {
> @@ -154,7 +153,6 @@ HttpUpdateSM::handle_api_return()
> }
> break;
> }
> -#endif //TS_NO_TRANSFORM
> case HttpTransact::PROXY_INTERNAL_CACHE_WRITE:
> case HttpTransact::SERVER_READ:
> case HttpTransact::PROXY_INTERNAL_CACHE_NOOP:
>
only now do I realize that you've not just been removing
TS_NO_API, but also TS_NO_TRANSFORM from the code as well..
--
Igor Galić
Tel: +43 (0) 664 886 22 883
Mail: i.galic@brainsware.org
URL: http://brainsware.org/
GPG: 6880 4155 74BD FD7C B515 2EA5 4B1D 9E08 A097 C9AE