diff --git a/frontend/TestSsiClient.h b/frontend/TestSsiClient.h index b5a228f51e6f628dca97e378cfbd6b91ae166702..4b2486150297e83f56b4924d638d4f7b333d59f9 100644 --- a/frontend/TestSsiClient.h +++ b/frontend/TestSsiClient.h @@ -21,7 +21,7 @@ extern XrdSsiProvider *XrdSsiProviderClient; -template <typename RequestType, typename ResponseType> +template <typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> class TestSsiClient { public: diff --git a/frontend/TestSsiRequest.cpp b/frontend/TestSsiRequest.cpp index f8d54cbe3bd2fd117c58fdadf8c22ead5adb2d7d..31988ae61a2818e60082ee11f9986b8559d446e9 100644 --- a/frontend/TestSsiRequest.cpp +++ b/frontend/TestSsiRequest.cpp @@ -40,6 +40,7 @@ bool TestSsiRequest::ProcessResponse(const XrdSsiErrInfo &eInfo, const XrdSsiRes // do something with metadata + // A metadata-only response is indicated when XrdSsiRespInfo::rType is set to isNil (i.e. no response data is present). #if 0 // clean up diff --git a/frontend/TestSsiRequestProc.cpp b/frontend/TestSsiRequestProc.cpp index c5675946e9dc617d73aa7a8d612a46a14ed0cb87..2eb3de557f2a27ec7f2a7e64e1e54d55d4c27054 100644 --- a/frontend/TestSsiRequestProc.cpp +++ b/frontend/TestSsiRequestProc.cpp @@ -8,7 +8,7 @@ // and metadata template <> -void RequestProc<xrdssi::test::Request, xrdssi::test::Result>::ExecuteAction() +void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert>::ExecuteAction() { // Output message in Json format (for debugging) @@ -27,11 +27,40 @@ void RequestProc<xrdssi::test::Request, xrdssi::test::Result>::ExecuteAction() } + +// A metadata-only reply is appropriate when we just need to send a short response/acknowledgement, +// as it has less overhead than a full response. The maximum amount of metadata that may be sent is +// defined by XrdSsiResponder::MaxMetaDataSZ constant member. + template <> -void RequestProc<xrdssi::test::Request, xrdssi::test::Result>::ExecuteMetadata() +void RequestProc<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert>::ExecuteMetadata() { std::cerr << "Sending metadata..." << std::endl; const std::string metadata("Have some metadata!"); SetMetadata(metadata.c_str(), metadata.size()); } + + +/* + * Alert messages can be anything you want them to be. The SSI framework enforces + * the following rules: + * + * - alerts are sent in the order posted, + * - all outstanding alerts are sent before the final response is sent (i.e. the one + * posted using a SetResponse() method), + * - once a final response is posted, subsequent alert messages are not sent, and + * - if a request is cancelled, all pending alerts are discarded. + * + * In order to send an alert, you must encapsulate your message using an + * XrdSsiRespInfoMsg object. The object provides synchronization between posting + * an alert, sending the alert, and releasing storage after the alert was sent. It is defined + * in the XrdSsiRespInfo.hh header file. + * + * The XrdSsiRespInfoMsg object needs to be inherited by whatever class you use to + * manage your alert message. The pure abstract class, RecycleMsg() must also be + * implemented. This method is called after the message is sent or when it is discarded. + * A parameter to the method tells you why it’s being called. + * + * See example p.45 + */ diff --git a/frontend/TestSsiRequestProc.h b/frontend/TestSsiRequestProc.h index 4ac4e5d242a232a8bc5c839c998ed45c2085cac8..501596253e975f299a1d4076bc7768ec1f6a7b74 100644 --- a/frontend/TestSsiRequestProc.h +++ b/frontend/TestSsiRequestProc.h @@ -18,7 +18,7 @@ * RequestProc is a kind of agent object that the service object creates for each request that it receives. */ -template <typename RequestType, typename ResponseType> +template <typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> class RequestProc : public XrdSsiResponder { public: @@ -41,8 +41,8 @@ private: -template <typename RequestType, typename ResponseType> -void RequestProc<RequestType, ResponseType>::Execute() +template <typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> +void RequestProc<RequestType, ResponseType, MetadataType, AlertType>::Execute() { using namespace std; @@ -98,8 +98,8 @@ void RequestProc<RequestType, ResponseType>::Execute() // Create specialized versions of this method to handle cancellation/cleanup for specific message types -template <typename RequestType, typename ResponseType> -void RequestProc<RequestType, ResponseType>::Finished(XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel) +template <typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> +void RequestProc<RequestType, ResponseType, MetadataType, AlertType>::Finished(XrdSsiRequest &rqstR, const XrdSsiRespInfo &rInfo, bool cancel) { using namespace std; diff --git a/frontend/TestSsiService.h b/frontend/TestSsiService.h index 168faad9992bb57ebd3bec4023ee107c9a8b4383..ddcc8b60c59186590dd6fb707d0229b1f34b121d 100644 --- a/frontend/TestSsiService.h +++ b/frontend/TestSsiService.h @@ -11,7 +11,7 @@ * Service Object, obtained using GetService() method of the TestSsiServiceProvider factory */ -template <typename RequestType, typename ResponseType> +template <typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> class TestSsiService : public XrdSsiService { public: @@ -32,12 +32,12 @@ public: -template <typename RequestType, typename ResponseType> -void TestSsiService<RequestType, ResponseType>::ProcessRequest(XrdSsiRequest &reqRef, XrdSsiResource &resRef) +template <typename RequestType, typename ResponseType, typename MetadataType, typename AlertType> +void TestSsiService<RequestType, ResponseType, MetadataType, AlertType>::ProcessRequest(XrdSsiRequest &reqRef, XrdSsiResource &resRef) { std::cerr << "Called ProcessRequest()" << std::endl; - RequestProc<RequestType, ResponseType> processor; + RequestProc<RequestType, ResponseType, MetadataType, AlertType> processor; // Bind the processor to the request. Inherits the BindRequest method from XrdSsiResponder. diff --git a/frontend/TestSsiServiceProvider.cpp b/frontend/TestSsiServiceProvider.cpp index 6e2c24607f1c2dfdce3700454b7d65a1e36130e4..0c7306800d1136b432d99ea9a43aaba2e1661cf1 100644 --- a/frontend/TestSsiServiceProvider.cpp +++ b/frontend/TestSsiServiceProvider.cpp @@ -43,7 +43,7 @@ XrdSsiService* TestSsiServiceProvider::GetService(XrdSsiErrInfo &eInfo, const st cerr << "Called GetService(" << contact << "," << oHold << ")" << endl; - XrdSsiService *ptr = new TestSsiService<xrdssi::test::Request, xrdssi::test::Result>; + XrdSsiService *ptr = new TestSsiService<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert>; return ptr; } diff --git a/frontend/test.proto b/frontend/test.proto index a1a9ccfb3430d73c53c8986dd4da7c9271468aea..9831f5505a8a3f92b13b6942f415c0511302ad57 100644 --- a/frontend/test.proto +++ b/frontend/test.proto @@ -33,9 +33,15 @@ message Result { } } -// XRootD SSI Service +// XRootD SSI Metadata -service XrdSsiService { - rpc SendRequest(Request) returns(Result); +message Metadata { + string message_text = 1; //< Some useful information about the next response +} + +// XRootD SSI Alert + +message Alert { + string message_text = 1; //< Some alert message for the client } diff --git a/frontend/test_client.cpp b/frontend/test_client.cpp index ebcf77c702d0b4aaaaf5c2c5c003f963ea8c72a3..2b9f5b687c215bba45ce199c903a7bb32ef25891 100644 --- a/frontend/test_client.cpp +++ b/frontend/test_client.cpp @@ -17,7 +17,7 @@ int main(int argc, char *argv[]) { // Obtain a Service Provider - TestSsiClient<xrdssi::test::Request, xrdssi::test::Result> test_ssi_service(host, port); + TestSsiClient<xrdssi::test::Request, xrdssi::test::Result, xrdssi::test::Metadata, xrdssi::test::Alert> test_ssi_service(host, port); // Create a Request object