Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
cta
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Harbor Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
dCache
cta
Commits
5f18153d
Commit
5f18153d
authored
7 years ago
by
Michael Davis
Browse files
Options
Downloads
Patches
Plain Diff
[XrdSsi] Adds callback objects
parent
38e4b98c
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
frontend/XrdSsiPbRequest.h
+89
-46
89 additions, 46 deletions
frontend/XrdSsiPbRequest.h
frontend/test_client.cpp
+22
-1
22 additions, 1 deletion
frontend/test_client.cpp
frontend/test_client.h
+1
-1
1 addition, 1 deletion
frontend/test_client.h
with
112 additions
and
48 deletions
frontend/XrdSsiPbRequest.h
+
89
−
46
View file @
5f18153d
...
...
@@ -3,11 +3,26 @@
#include
<XrdSsi/XrdSsiRequest.hh>
// XRootD SSI + Protocol Buffers callbacks.
// The client should define a specialized callback type for each XRootD reply type (Response, Metadata, Alert)
template
<
typename
CallbackArg
>
class
XrdSsiPbRequestCallback
{
public:
void
operator
()(
const
CallbackArg
&
arg
);
};
// XRootD SSI + Protocol Buffers Request class
template
<
typename
RequestType
,
typename
ResponseType
,
typename
MetadataType
,
typename
AlertType
>
class
XrdSsiPbRequest
:
public
XrdSsiRequest
{
public:
XrdSsiPbRequest
(
const
std
::
string
&
buffer_str
,
uint16_t
timeout
=
0
)
:
request_buffer
(
buffer_str
.
c_str
()),
request_len
(
buffer_str
.
size
())
{
std
::
cerr
<<
"Creating TestSsiRequest object, setting timeout="
<<
timeout
<<
std
::
endl
;
...
...
@@ -45,9 +60,18 @@ public:
virtual
void
Alert
(
XrdSsiRespInfoMsg
&
aMsg
)
override
;
private
:
const
char
*
request_buffer
;
int
request_len
;
// Callbacks for each of the XRootD response types
XrdSsiPbRequestCallback
<
RequestType
>
RequestCallback
;
XrdSsiPbRequestCallback
<
MetadataType
>
MetadataCallback
;
XrdSsiPbRequestCallback
<
AlertType
>
AlertCallback
;
// Additional callback for handling errors from the XRootD framework
XrdSsiPbRequestCallback
<
std
::
string
>
ErrorCallback
;
};
...
...
@@ -61,72 +85,91 @@ bool XrdSsiPbRequest<RequestType, ResponseType, MetadataType, AlertType>::Proces
cerr
<<
"ProcessResponse() callback called with response type = "
<<
rInfo
.
State
()
<<
endl
;
if
(
eInfo
.
hasError
()
)
switch
(
rInfo
.
rType
)
{
// Handle error
u
sin
g
the
passed eInfo object
// Handle errors
in the
XRootD framework (e.g. no response from server)
cerr
<<
"Error = "
<<
eInfo
.
Get
()
<<
endl
;
case
XrdSsiRespInfo
::
isError
:
ErrorCallback
(
eInfo
.
Get
());
Finished
();
// Return control of the object to the calling thread and delete rInfo
Finished
();
// Returns control of the object to the calling thread
// Deletes rInfo
// Andy says you can now do a "delete this"
// Andy says it is now safe to delete the Request object, which implies that the pointer on the calling side
// will never refer to it again and the destructor of the base class doesn't access any class members.
delete
this
;
// well, OK, so long as you are 100% sure that this object was allocated by new,
// that the pointer on the calling side will never refer to it again, that the
// destructor of the base class doesn't access any class members, ...
}
else
{
// Arbitrary metadata can be sent ahead of the response data, for example to describe the
// response so that it can be handled in the most optimum way. To access the metadata, call
// GetMetadata() before calling GetResponseData().
delete
this
;
break
;
int
myMetadataLen
;
case
XrdSsiRespInfo
::
isHandle
:
// To implement detached requests, add another callback type which saves the handle
ErrorCallback
(
"Detached requests are not implemented."
);
Finished
();
delete
this
;
break
;
GetMetadata
(
myMetadataLen
);
case
XrdSsiRespInfo
::
isFile
:
// To implement file requests, add another callback type
ErrorCallback
(
"File requests are not implemented."
);
Finished
();
delete
this
;
break
;
if
(
rInfo
.
rType
==
XrdSsiRespInfo
::
isData
&&
myMetadataLen
>
0
)
{
cerr
<<
"Response has "
<<
myMetadataLen
<<
" bytes of metadata."
<<
endl
;
case
XrdSsiRespInfo
::
isStream
:
// To implement stream requests, add another callback type
ErrorCallback
(
"Stream requests are not implemented."
);
Finished
();
delete
this
;
break
;
// do something with metadata
case
XrdSsiRespInfo
::
isNone
:
case
XrdSsiRespInfo
::
isData
:
// Check for metadata: Arbitrary metadata can be sent ahead of the response data, for example to
// describe the response so that it can be handled in the most optimal way.
// A metadata-only response is indicated when XrdSsiRespInfo::rType is set to isNil (i.e. no response data is present).
#if 0
// clean up
int
metadata_len
;
const
char
*
metadata_buffer
=
GetMetadata
(
metadata_len
);
Finished();
if
(
metadata_len
>
0
)
{
// Deserialize the metadata
delete this;
#endif
}
const
std
::
string
metadata_str
(
metadata_buffer
,
metadata_len
);
std
::
cerr
<<
"metadata_str = "
<<
metadata_str
<<
std
::
endl
;
if
(
rInfo
.
rType
==
XrdSsiRespInfo
::
isHandle
)
{
cerr
<<
"Response is detached, handle = "
<<
endl
;
MetadataType
metadata
;
// copy the handle somewhere
if
(
!
metadata
.
ParseFromString
(
metadata_str
))
{
ErrorCallback
(
"metadata.ParseFromString() failed"
);
Finished
();
delete
this
;
break
;
}
// clean up
MetadataCallback
(
metadata
);
Finished
();
// If this is a metadata-only response, there is nothing more to do
delete
this
;
}
if
(
rInfo
.
rType
==
XrdSsiRespInfo
::
isNone
)
{
Finished
();
delete
this
;
break
;
}
}
if
(
rInfo
.
rType
==
XrdSsiRespInfo
::
isData
)
{
// A proper data response type
// Handle messages
static
const
int
myBSize
=
1024
;
if
(
rInfo
.
rType
==
XrdSsiRespInfo
::
isData
)
{
static
const
int
myBSize
=
1024
;
char
*
myBuff
=
reinterpret_cast
<
char
*>
(
malloc
(
myBSize
));
char
*
myBuff
=
reinterpret_cast
<
char
*>
(
malloc
(
myBSize
));
GetResponseData
(
myBuff
,
myBSize
);
}
GetResponseData
(
myBuff
,
myBSize
);
}
}
return
true
;
// you should always return true. (So why not make the return type void?)
return
true
;
}
...
...
This diff is collapsed.
Click to expand it.
frontend/test_client.cpp
+
22
−
1
View file @
5f18153d
#include
"test_util.h"
// for Json output (only needed for debugging)
#include
"test_client.h"
// Binds XRootD SSI to Google Protocol buffer
// Define the location of the XRootD SSI Service
...
...
@@ -10,6 +9,28 @@ const std::string resource = "/test";
// Error callback
// This is for framework errors, e.g. no response from server. Server errors will be returned in the Metadata or Alert callbacks.
template
<
>
void
XrdSsiPbRequestCallback
<
std
::
string
>::
operator
()(
const
std
::
string
&
error_txt
)
{
std
::
cerr
<<
"ErrorCallback():"
<<
std
::
endl
<<
error_txt
<<
std
::
endl
;
}
// Metadata callback
template
<
>
void
XrdSsiPbRequestCallback
<
xrdssi
::
test
::
Metadata
>::
operator
()(
const
xrdssi
::
test
::
Metadata
&
metadata
)
{
std
::
cout
<<
"MetadataCallback():"
<<
std
::
endl
;
std
::
cout
<<
MessageToJsonString
(
metadata
);
}
int
main
(
int
argc
,
char
*
argv
[])
{
// Verify that the version of the Google Protocol Buffer library that we linked against is
...
...
This diff is collapsed.
Click to expand it.
frontend/test_client.h
+
1
−
1
View file @
5f18153d
...
...
@@ -9,7 +9,7 @@
#include
"XrdSsiPbServiceClientSide.h"
// XRootD SSI Service API
#include
"test.pb.h"
// Auto-generated message types from .proto file
// Bind the type of the XrdSsi
Client
to the types defined in the .proto file
// Bind the type of the XrdSsi
Service
to the types defined in the .proto file
typedef
XrdSsiPbServiceClientSide
<
xrdssi
::
test
::
Request
,
// Request message type
xrdssi
::
test
::
Result
,
// Response message type
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment