Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
pistache
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
pistache
Commits
ec6ee3b9
Commit
ec6ee3b9
authored
Dec 01, 2015
by
octal
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Experimenting with a timeout API
parent
a750622f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
146 additions
and
18 deletions
+146
-18
main.cc
main.cc
+17
-0
src/http.cc
src/http.cc
+24
-9
src/http.h
src/http.h
+5
-4
src/io.cc
src/io.cc
+64
-3
src/io.h
src/io.h
+30
-0
src/peer.cc
src/peer.cc
+1
-1
src/peer.h
src/peer.h
+5
-1
No files found.
main.cc
View file @
ec6ee3b9
...
@@ -7,6 +7,16 @@
...
@@ -7,6 +7,16 @@
using
namespace
std
;
using
namespace
std
;
struct
ExceptionPrinter
{
void
operator
()(
std
::
exception_ptr
exc
)
const
{
try
{
std
::
rethrow_exception
(
exc
);
}
catch
(
const
std
::
exception
&
e
)
{
std
::
cerr
<<
"An exception occured: "
<<
e
.
what
()
<<
std
::
endl
;
}
}
};
class
MyHandler
:
public
Net
::
Http
::
Handler
{
class
MyHandler
:
public
Net
::
Http
::
Handler
{
void
onRequest
(
const
Net
::
Http
::
Request
&
req
,
Net
::
Http
::
Response
response
)
{
void
onRequest
(
const
Net
::
Http
::
Request
&
req
,
Net
::
Http
::
Response
response
)
{
if
(
req
.
resource
()
==
"/ping"
)
{
if
(
req
.
resource
()
==
"/ping"
)
{
...
@@ -37,6 +47,13 @@ class MyHandler : public Net::Http::Handler {
...
@@ -37,6 +47,13 @@ class MyHandler : public Net::Http::Handler {
else
if
(
req
.
resource
()
==
"/exception"
)
{
else
if
(
req
.
resource
()
==
"/exception"
)
{
throw
std
::
runtime_error
(
"Exception thrown in the handler"
);
throw
std
::
runtime_error
(
"Exception thrown in the handler"
);
}
}
else
if
(
req
.
resource
()
==
"/timeout"
)
{
response
.
timeoutAfter
(
std
::
chrono
::
seconds
(
1
))
.
then
([
=
](
Net
::
Http
::
Response
*
response
)
{
response
->
send
(
Net
::
Http
::
Code
::
Bad_Request
,
"Timeout occured"
);
},
Async
::
NoExcept
);
}
}
}
};
};
...
...
src/http.cc
View file @
ec6ee3b9
...
@@ -348,18 +348,33 @@ Request::query() const {
...
@@ -348,18 +348,33 @@ Request::query() const {
return
query_
;
return
query_
;
}
}
void
Async
::
Promise
<
Response
*>
ResponseWriter
::
writeStatusLine
()
{
Response
::
timeoutAfter
(
std
::
chrono
::
milliseconds
timeout
)
}
{
#if 0
void
Async::Promise<uint64_t> promise([=](Async::Resolver& resolve, Async::Rejection& reject) {
ResponseWriter
::
writeHeaders
()
{
peer()->io()->setTimeout(timeout, resolve, reject);
std
::
ostream
os
(
&
stream_
);
});
promise.then([=](uint64_t) {
send(Code::Bad_Request, "A timeout occured");
}, Async::NoExcept);
return promise;
#endif
Async
::
Promise
<
uint64_t
>
promise
([
=
](
Async
::
Resolver
&
resolve
,
Async
::
Rejection
&
reject
)
{
peer
()
->
io
()
->
setTimeout
(
timeout
,
resolve
,
reject
);
});
return
promise
.
then
([
=
](
uint64_t
)
{
auto
p
=
Async
::
Promise
<
Response
*>::
resolved
(
this
);
return
p
;
},
Async
::
NoExcept
);
}
}
Async
::
Promise
<
ssize_t
>
Async
::
Promise
<
ssize_t
>
ResponseWriter
::
send
()
ResponseWriter
::
send
()
const
{
{
auto
body
=
stream_
.
buffer
();
auto
body
=
stream_
.
buffer
();
...
...
src/http.h
View file @
ec6ee3b9
...
@@ -131,7 +131,7 @@ public:
...
@@ -131,7 +131,7 @@ public:
return
&
stream_
;
return
&
stream_
;
}
}
Async
::
Promise
<
ssize_t
>
send
();
Async
::
Promise
<
ssize_t
>
send
()
const
;
private:
private:
ResponseWriter
(
Message
&&
other
,
size_t
size
,
std
::
weak_ptr
<
Tcp
::
Peer
>
peer
)
ResponseWriter
(
Message
&&
other
,
size_t
size
,
std
::
weak_ptr
<
Tcp
::
Peer
>
peer
)
...
@@ -156,9 +156,6 @@ private:
...
@@ -156,9 +156,6 @@ private:
return
peer_
.
lock
();
return
peer_
.
lock
();
}
}
void
writeStatusLine
();
void
writeHeaders
();
NetworkStream
stream_
;
NetworkStream
stream_
;
std
::
weak_ptr
<
Tcp
::
Peer
>
peer_
;
std
::
weak_ptr
<
Tcp
::
Peer
>
peer_
;
};
};
...
@@ -182,6 +179,8 @@ public:
...
@@ -182,6 +179,8 @@ public:
return
*
this
;
return
*
this
;
}
}
Response
(
const
Response
&
other
)
=
default
;
const
Header
::
Collection
&
headers
()
const
{
const
Header
::
Collection
&
headers
()
const
{
return
headers_
;
return
headers_
;
}
}
...
@@ -235,6 +234,8 @@ public:
...
@@ -235,6 +234,8 @@ public:
return
ResponseWriter
(
std
::
move
(
*
this
),
size
,
peer_
);
return
ResponseWriter
(
std
::
move
(
*
this
),
size
,
peer_
);
}
}
Async
::
Promise
<
Response
*>
timeoutAfter
(
std
::
chrono
::
milliseconds
timeout
);
private:
private:
Response
()
Response
()
:
Message
()
:
Message
()
...
...
src/io.cc
View file @
ec6ee3b9
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
#include "listener.h"
#include "listener.h"
#include "peer.h"
#include "peer.h"
#include "os.h"
#include "os.h"
#include <sys/timerfd.h>
namespace
Net
{
namespace
Net
{
...
@@ -35,6 +36,8 @@ To *message_cast(const std::unique_ptr<Message>& from)
...
@@ -35,6 +36,8 @@ To *message_cast(const std::unique_ptr<Message>& from)
}
}
IoWorker
::
IoWorker
()
{
IoWorker
::
IoWorker
()
{
timerFd
=
TRY_RET
(
timerfd_create
(
CLOCK_MONOTONIC
,
TFD_NONBLOCK
));
poller
.
addFd
(
timerFd
,
Polling
::
NotifyOn
::
Read
,
Polling
::
Tag
(
timerFd
));
}
}
IoWorker
::~
IoWorker
()
{
IoWorker
::~
IoWorker
()
{
...
@@ -70,6 +73,36 @@ IoWorker::pin(const CpuSet& set) {
...
@@ -70,6 +73,36 @@ IoWorker::pin(const CpuSet& set) {
}
}
}
}
void
IoWorker
::
setTimeoutMs
(
std
::
chrono
::
milliseconds
value
,
Async
::
Resolver
resolve
,
Async
::
Rejection
reject
)
{
itimerspec
spec
;
spec
.
it_interval
.
tv_sec
=
0
;
spec
.
it_interval
.
tv_nsec
=
0
;
if
(
value
.
count
()
<
1000
)
{
spec
.
it_value
.
tv_sec
=
0
;
spec
.
it_value
.
tv_nsec
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
nanoseconds
>
(
value
).
count
();
}
else
{
spec
.
it_value
.
tv_sec
=
std
::
chrono
::
duration_cast
<
std
::
chrono
::
seconds
>
(
value
).
count
();
spec
.
it_value
.
tv_nsec
=
0
;
}
int
res
=
timerfd_settime
(
timerFd
,
0
,
&
spec
,
0
);
if
(
res
==
-
1
)
{
reject
(
Error
::
system
(
"Could not set timer time"
));
return
;
}
timeout
=
Some
(
Timeout
(
value
,
std
::
move
(
resolve
),
std
::
move
(
reject
)));
}
void
void
IoWorker
::
shutdown
()
{
IoWorker
::
shutdown
()
{
mailbox
.
post
(
new
ShutdownMessage
());
mailbox
.
post
(
new
ShutdownMessage
());
...
@@ -149,7 +182,7 @@ IoWorker::handleNewPeer(const std::shared_ptr<Peer>& peer)
...
@@ -149,7 +182,7 @@ IoWorker::handleNewPeer(const std::shared_ptr<Peer>& peer)
peers
.
insert
(
std
::
make_pair
(
fd
,
peer
));
peers
.
insert
(
std
::
make_pair
(
fd
,
peer
));
}
}
peer
->
io
=
this
;
peer
->
io
_
=
this
;
handler_
->
onConnection
(
peer
);
handler_
->
onConnection
(
peer
);
poller
.
addFd
(
fd
,
NotifyOn
::
Read
,
Polling
::
Tag
(
fd
),
Polling
::
Mode
::
Edge
);
poller
.
addFd
(
fd
,
NotifyOn
::
Read
,
Polling
::
Tag
(
fd
),
Polling
::
Mode
::
Edge
);
...
@@ -184,9 +217,14 @@ IoWorker::run() {
...
@@ -184,9 +217,14 @@ IoWorker::run() {
return
;
return
;
}
}
}
else
{
}
else
{
auto
&
peer
=
getPeer
(
event
.
tag
);
if
(
event
.
flags
.
hasFlag
(
NotifyOn
::
Read
))
{
if
(
event
.
flags
.
hasFlag
(
NotifyOn
::
Read
))
{
handleIncoming
(
peer
);
auto
fd
=
event
.
tag
.
value
();
if
(
fd
==
timerFd
)
{
handleTimeout
();
}
else
{
auto
&
peer
=
getPeer
(
event
.
tag
);
handleIncoming
(
peer
);
}
}
}
else
if
(
event
.
flags
.
hasFlag
(
NotifyOn
::
Write
))
{
else
if
(
event
.
flags
.
hasFlag
(
NotifyOn
::
Write
))
{
auto
fd
=
event
.
tag
.
value
();
auto
fd
=
event
.
tag
.
value
();
...
@@ -216,6 +254,29 @@ IoWorker::run() {
...
@@ -216,6 +254,29 @@ IoWorker::run() {
}
}
}
}
void
IoWorker
::
handleTimeout
()
{
auto
&
entry
=
timeout
.
unsafeGet
();
uint64_t
numWakeups
;
int
res
=
::
read
(
timerFd
,
&
numWakeups
,
sizeof
numWakeups
);
if
(
res
==
-
1
)
{
if
(
errno
==
EAGAIN
||
errno
==
EWOULDBLOCK
)
return
;
else
entry
.
reject
(
Error
::
system
(
"Could not read timerfd"
));
}
else
{
if
(
res
!=
sizeof
(
numWakeups
))
{
entry
.
reject
(
Error
(
"Read invalid number of bytes for timer fd: "
+
std
::
to_string
(
timerFd
)));
}
else
{
entry
.
resolve
(
numWakeups
);
}
}
}
Async
::
Promise
<
ssize_t
>
Async
::
Promise
<
ssize_t
>
IoWorker
::
asyncWrite
(
Fd
fd
,
const
void
*
buf
,
size_t
len
)
{
IoWorker
::
asyncWrite
(
Fd
fd
,
const
void
*
buf
,
size_t
len
)
{
return
Async
::
Promise
<
ssize_t
>
([
=
](
Async
::
Resolver
&
resolve
,
Async
::
Rejection
&
reject
)
{
return
Async
::
Promise
<
ssize_t
>
([
=
](
Async
::
Resolver
&
resolve
,
Async
::
Rejection
&
reject
)
{
...
...
src/io.h
View file @
ec6ee3b9
...
@@ -39,6 +39,13 @@ public:
...
@@ -39,6 +39,13 @@ public:
void
pin
(
const
CpuSet
&
set
);
void
pin
(
const
CpuSet
&
set
);
void
shutdown
();
void
shutdown
();
template
<
typename
Duration
>
void
setTimeout
(
Duration
timeout
,
Async
::
Resolver
resolve
,
Async
::
Rejection
reject
)
{
setTimeoutMs
(
std
::
chrono
::
duration_cast
<
std
::
chrono
::
milliseconds
>
(
timeout
),
std
::
move
(
resolve
),
std
::
move
(
reject
));
}
private:
private:
struct
OnHoldWrite
{
struct
OnHoldWrite
{
...
@@ -57,11 +64,33 @@ private:
...
@@ -57,11 +64,33 @@ private:
size_t
len
;
size_t
len
;
};
};
void
setTimeoutMs
(
std
::
chrono
::
milliseconds
value
,
Async
::
Resolver
,
Async
::
Rejection
reject
);
struct
Timeout
{
Timeout
(
std
::
chrono
::
milliseconds
value
,
Async
::
Resolver
resolve
,
Async
::
Rejection
reject
)
:
value
(
value
)
,
resolve
(
std
::
move
(
resolve
))
,
reject
(
std
::
move
(
reject
))
{
}
std
::
chrono
::
milliseconds
value
;
Async
::
Resolver
resolve
;
Async
::
Rejection
reject
;
};
Polling
::
Epoll
poller
;
Polling
::
Epoll
poller
;
std
::
unique_ptr
<
std
::
thread
>
thread
;
std
::
unique_ptr
<
std
::
thread
>
thread
;
mutable
std
::
mutex
peersMutex
;
mutable
std
::
mutex
peersMutex
;
std
::
unordered_map
<
Fd
,
std
::
shared_ptr
<
Peer
>>
peers
;
std
::
unordered_map
<
Fd
,
std
::
shared_ptr
<
Peer
>>
peers
;
std
::
unordered_map
<
Fd
,
OnHoldWrite
>
toWrite
;
std
::
unordered_map
<
Fd
,
OnHoldWrite
>
toWrite
;
Optional
<
Timeout
>
timeout
;
Fd
timerFd
;
std
::
shared_ptr
<
Handler
>
handler_
;
std
::
shared_ptr
<
Handler
>
handler_
;
Flags
<
Options
>
options_
;
Flags
<
Options
>
options_
;
...
@@ -73,6 +102,7 @@ private:
...
@@ -73,6 +102,7 @@ private:
Async
::
Promise
<
ssize_t
>
asyncWrite
(
Fd
fd
,
const
void
*
buf
,
size_t
len
);
Async
::
Promise
<
ssize_t
>
asyncWrite
(
Fd
fd
,
const
void
*
buf
,
size_t
len
);
void
handleIncoming
(
const
std
::
shared_ptr
<
Peer
>&
peer
);
void
handleIncoming
(
const
std
::
shared_ptr
<
Peer
>&
peer
);
void
handleTimeout
();
void
run
();
void
run
();
};
};
...
...
src/peer.cc
View file @
ec6ee3b9
...
@@ -79,7 +79,7 @@ Peer::tryGetData(std::string(name)) const {
...
@@ -79,7 +79,7 @@ Peer::tryGetData(std::string(name)) const {
Async
::
Promise
<
ssize_t
>
Async
::
Promise
<
ssize_t
>
Peer
::
send
(
const
void
*
buf
,
size_t
len
)
{
Peer
::
send
(
const
void
*
buf
,
size_t
len
)
{
return
io
->
asyncWrite
(
fd_
,
buf
,
len
);
return
io
_
->
asyncWrite
(
fd_
,
buf
,
len
);
}
}
...
...
src/peer.h
View file @
ec6ee3b9
...
@@ -52,8 +52,12 @@ public:
...
@@ -52,8 +52,12 @@ public:
Async
::
Promise
<
ssize_t
>
send
(
const
void
*
buf
,
size_t
len
);
Async
::
Promise
<
ssize_t
>
send
(
const
void
*
buf
,
size_t
len
);
IoWorker
*
io
()
{
return
io_
;
}
private:
private:
IoWorker
*
io
;
IoWorker
*
io
_
;
Address
addr
;
Address
addr
;
std
::
string
hostname_
;
std
::
string
hostname_
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment