Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
actor-incubator
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
cpp-libs
actor-incubator
Commits
03756ae4
Commit
03756ae4
authored
Oct 11, 2019
by
Jakob Otto
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor stream_transport
parent
c4e5343e
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
107 additions
and
67 deletions
+107
-67
libcaf_net/caf/net/stream_transport.hpp
libcaf_net/caf/net/stream_transport.hpp
+52
-26
libcaf_net/test/stream_transport.cpp
libcaf_net/test/stream_transport.cpp
+5
-4
libcaf_net/test/string_application.cpp
libcaf_net/test/string_application.cpp
+13
-8
libcaf_net/test/transport_worker.cpp
libcaf_net/test/transport_worker.cpp
+11
-7
libcaf_net/test/transport_worker_dispatcher.cpp
libcaf_net/test/transport_worker_dispatcher.cpp
+26
-22
No files found.
libcaf_net/caf/net/stream_transport.hpp
View file @
03756ae4
...
...
@@ -20,6 +20,7 @@
#include "caf/byte.hpp"
#include "caf/error.hpp"
#include "caf/expected.hpp"
#include "caf/fwd.hpp"
#include "caf/logger.hpp"
#include "caf/net/endpoint_manager.hpp"
...
...
@@ -200,12 +201,17 @@ public:
prepare_next_read
();
}
void
write_packet
(
span
<
const
byte
>
header
,
span
<
const
byte
>
payload
,
typename
worker_type
::
id_type
)
{
if
(
write_buf_
.
empty
())
void
write_packet
(
unit_t
,
span
<
buffer_type
*>
buffers
)
{
// Sanity check
CAF_ASSERT
(
!
buffers
.
empty
());
auto
it
=
buffers
.
begin
();
if
(
write_queue_
.
empty
())
manager
().
register_writing
();
write_buf_
.
insert
(
write_buf_
.
end
(),
header
.
begin
(),
header
.
end
());
write_buf_
.
insert
(
write_buf_
.
end
(),
payload
.
begin
(),
payload
.
end
());
// move header by itself to keep things sorted.
write_queue_
.
emplace_back
(
true
,
std
::
move
(
**
it
++
));
// payload buffers. just write them
for
(;
it
!=
buffers
.
end
();
++
it
)
write_queue_
.
emplace_back
(
false
,
std
::
move
(
**
it
));
}
// -- buffer recycling -------------------------------------------------------
...
...
@@ -232,30 +238,50 @@ private:
// -- private member functions -----------------------------------------------
bool
write_some
()
{
if
(
write_buf_
.
empty
())
auto
begin
=
[
&
]()
{
return
write_queue_
.
begin
();
};
// helper to sort empty buffers back into the right queues
auto
recycle
=
[
&
]()
{
auto
is_header
=
[](
std
::
pair
<
bool
,
buffer_type
>&
p
)
{
return
p
.
first
;
};
begin
()
->
second
.
clear
();
if
(
is_header
(
*
begin
()))
free_header_bufs_
.
emplace_back
(
std
::
move
(
begin
()
->
second
));
else
free_bufs_
.
emplace_back
(
std
::
move
(
begin
()
->
second
));
write_queue_
.
pop_front
();
};
// nothing to write
if
(
write_queue_
.
empty
())
return
false
;
auto
len
=
write_buf_
.
size
()
-
written_
;
auto
buf
=
write_buf_
.
data
()
+
written_
;
CAF_LOG_TRACE
(
CAF_ARG
(
handle_
.
id
)
<<
CAF_ARG
(
len
));
auto
ret
=
write
(
handle_
,
make_span
(
buf
,
len
));
if
(
auto
num_bytes
=
get_if
<
size_t
>
(
&
ret
))
{
CAF_LOG_DEBUG
(
CAF_ARG
(
len
)
<<
CAF_ARG
(
handle_
.
id
)
<<
CAF_ARG
(
*
num_bytes
));
// Update state.
written_
+=
*
num_bytes
;
if
(
written_
>=
write_buf_
.
size
())
{
written_
=
0
;
write_buf_
.
clear
();
do
{
if
(
begin
()
->
second
.
empty
())
{
recycle
();
continue
;
}
// get size of send buffer
auto
ret
=
send_buffer_size
(
handle_
);
if
(
!
ret
)
{
CAF_LOG_ERROR
(
"send_buffer_size returned an error"
<<
CAF_ARG
(
ret
));
return
false
;
}
// is send buffer of socket full?
if
(
begin
()
->
second
.
size
()
>
*
ret
)
return
true
;
CAF_LOG_TRACE
(
CAF_ARG
(
handle_
.
id
));
auto
write_ret
=
write
(
handle_
,
make_span
(
begin
()
->
second
));
if
(
auto
num_bytes
=
get_if
<
size_t
>
(
&
write_ret
))
{
CAF_LOG_DEBUG
(
CAF_ARG
(
handle_
.
id
)
<<
CAF_ARG
(
*
num_bytes
));
if
(
*
num_bytes
>=
begin
()
->
second
.
size
())
recycle
();
}
else
{
auto
err
=
get
<
sec
>
(
ret
);
auto
err
=
get
<
sec
>
(
write_
ret
);
if
(
err
!=
sec
::
unavailable_or_would_block
)
{
CAF_LOG_DEBUG
(
"send failed"
<<
CAF_ARG
(
err
));
worker_
.
handle_error
(
err
);
return
false
;
}
}
return
true
;
}
while
(
!
write_queue_
.
empty
());
return
false
;
}
worker_type
worker_
;
...
...
@@ -265,7 +291,7 @@ private:
std
::
deque
<
buffer_type
>
free_bufs_
;
buffer_type
read_buf_
;
buffer_type
write_buf
_
;
std
::
deque
<
std
::
pair
<
bool
,
buffer_type
>>
write_queue
_
;
// TODO implement retries using this member!
// size_t max_consecutive_reads_;
...
...
libcaf_net/test/stream_transport.cpp
View file @
03756ae4
...
...
@@ -71,10 +71,11 @@ public:
return
none
;
}
template
<
class
Transport
>
void
write_message
(
Transport
&
transport
,
std
::
unique_ptr
<
endpoint_manager_queue
::
message
>
msg
)
{
transport
.
write_packet
(
span
<
byte
>
{},
msg
->
payload
);
template
<
class
Parent
>
void
write_message
(
Parent
&
parent
,
std
::
unique_ptr
<
endpoint_manager_queue
::
message
>
ptr
)
{
auto
header_buf
=
parent
.
next_header_buffer
();
parent
.
write_packet
(
header_buf
,
ptr
->
payload
);
}
template
<
class
Parent
>
...
...
libcaf_net/test/string_application.cpp
View file @
03756ae4
...
...
@@ -43,6 +43,8 @@ using namespace caf::policy;
namespace
{
using
buffer_type
=
std
::
vector
<
byte
>
;
struct
fixture
:
test_coordinator_fixture
<>
,
host_fixture
{
fixture
()
{
mpx
=
std
::
make_shared
<
multiplexer
>
();
...
...
@@ -98,13 +100,15 @@ public:
template
<
class
Parent
>
void
write_message
(
Parent
&
parent
,
std
::
unique_ptr
<
endpoint_manager_queue
::
message
>
msg
)
{
std
::
unique_ptr
<
endpoint_manager_queue
::
message
>
ptr
)
{
// Ignore proxy announcement messages.
if
(
msg
->
msg
==
nullptr
)
if
(
ptr
->
msg
==
nullptr
)
return
;
header_type
header
{
static_cast
<
uint32_t
>
(
msg
->
payload
.
size
())};
std
::
vector
<
byte
>
payload
(
msg
->
payload
.
begin
(),
msg
->
payload
.
end
());
parent
.
write_packet
(
as_bytes
(
make_span
(
&
header
,
1
)),
make_span
(
payload
));
auto
header_buf
=
parent
.
next_header_buffer
();
serializer_impl
<
buffer_type
>
sink
{
sys_
,
header_buf
};
header_type
header
{
static_cast
<
uint32_t
>
(
ptr
->
payload
.
size
())};
sink
(
header
);
parent
.
write_packet
(
header_buf
,
ptr
->
payload
);
}
static
expected
<
std
::
vector
<
byte
>>
serialize
(
actor_system
&
sys
,
...
...
@@ -147,7 +151,8 @@ public:
}
else
{
if
(
data
.
size
()
!=
sizeof
(
header_type
))
CAF_FAIL
(
""
);
memcpy
(
&
header_
,
data
.
data
(),
sizeof
(
header_type
));
binary_deserializer
source
{
nullptr
,
data
};
source
(
header_
);
if
(
header_
.
payload
==
0
)
Base
::
handle_packet
(
parent
,
header_
,
span
<
const
byte
>
{});
else
...
...
@@ -187,8 +192,8 @@ public:
// nop
}
void
handle_error
(
sec
)
{
// nop
void
handle_error
(
sec
sec
)
{
CAF_FAIL
(
"handle_error called: "
<<
CAF_ARG
(
sec
));
}
private:
...
...
libcaf_net/test/transport_worker.cpp
View file @
03756ae4
...
...
@@ -37,6 +37,8 @@ using namespace caf::net;
namespace
{
using
buffer_type
=
std
::
vector
<
byte
>
;
constexpr
string_view
hello_test
=
"hello test!"
;
struct
application_result
{
...
...
@@ -72,7 +74,8 @@ public:
template
<
class
Parent
>
void
write_message
(
Parent
&
parent
,
std
::
unique_ptr
<
endpoint_manager_queue
::
message
>
msg
)
{
parent
.
write_packet
(
span
<
const
byte
>
{},
msg
->
payload
);
auto
header_buffer
=
parent
.
next_header_buffer
();
parent
.
write_packet
(
header_buffer
,
msg
->
payload
);
}
template
<
class
Parent
>
...
...
@@ -118,16 +121,17 @@ public:
using
application_type
=
dummy_application
;
dummy_transport
(
std
::
shared_ptr
<
transport_result
>
res
)
:
res_
(
res
)
{
dummy_transport
(
std
::
shared_ptr
<
transport_result
>
res
)
:
res_
(
std
::
move
(
res
))
{
// nop
}
void
write_packet
(
span
<
const
byte
>
header
,
span
<
const
byte
>
payload
,
ip_endpoint
ep
)
{
auto
&
buf
=
res_
->
packet_buffer
;
buf
.
insert
(
buf
.
begin
(),
header
.
begin
(),
header
.
end
());
buf
.
insert
(
buf
.
begin
(),
payload
.
begin
(),
payload
.
end
());
void
write_packet
(
ip_endpoint
ep
,
span
<
buffer_type
*>
buffers
)
{
res_
->
ep
=
ep
;
auto
&
packet_buf
=
res_
->
packet_buffer
;
packet_buf
.
clear
();
for
(
auto
buf
:
buffers
)
packet_buf
.
insert
(
packet_buf
.
end
(),
buf
->
begin
(),
buf
->
end
());
}
transport_type
&
transport
()
{
...
...
libcaf_net/test/transport_worker_dispatcher.cpp
View file @
03756ae4
...
...
@@ -33,6 +33,8 @@ using namespace caf::net;
namespace
{
using
buffer_type
=
std
::
vector
<
byte
>
;
constexpr
string_view
hello_test
=
"hello_test"
;
struct
dummy_actor
:
public
monitorable_actor
{
...
...
@@ -47,7 +49,7 @@ struct dummy_actor : public monitorable_actor {
class
dummy_application
{
public:
dummy_application
(
std
::
shared_ptr
<
std
::
vector
<
byte
>
>
rec_buf
,
uint8_t
id
)
dummy_application
(
std
::
shared_ptr
<
buffer_type
>
rec_buf
,
uint8_t
id
)
:
rec_buf_
(
std
::
move
(
rec_buf
)),
id_
(
id
){
// nop
...
...
@@ -61,11 +63,12 @@ public:
return
none
;
}
template
<
class
Transpor
t
>
void
write_message
(
Transport
&
transpor
t
,
template
<
class
Paren
t
>
void
write_message
(
Parent
&
paren
t
,
std
::
unique_ptr
<
endpoint_manager_queue
::
message
>
msg
)
{
rec_buf_
->
push_back
(
static_cast
<
byte
>
(
id_
));
transport
.
write_packet
(
span
<
byte
>
{},
make_span
(
msg
->
payload
));
auto
header_buf
=
parent
.
next_header_buffer
();
parent
.
write_packet
(
header_buf
,
msg
->
payload
);
}
template
<
class
Parent
>
...
...
@@ -88,13 +91,13 @@ public:
rec_buf_
->
push_back
(
static_cast
<
byte
>
(
id_
));
}
static
expected
<
std
::
vector
<
byte
>
>
serialize
(
actor_system
&
,
static
expected
<
buffer_type
>
serialize
(
actor_system
&
,
const
type_erased_tuple
&
)
{
return
std
::
vector
<
byte
>
{};
return
buffer_type
{};
}
private:
std
::
shared_ptr
<
std
::
vector
<
byte
>
>
rec_buf_
;
std
::
shared_ptr
<
buffer_type
>
rec_buf_
;
uint8_t
id_
;
};
...
...
@@ -102,8 +105,8 @@ struct dummy_application_factory {
public:
using
application_type
=
dummy_application
;
dummy_application_factory
(
std
::
shared_ptr
<
std
::
vector
<
byte
>
>
buf
)
:
buf_
(
buf
),
application_cnt_
(
0
)
{
dummy_application_factory
(
std
::
shared_ptr
<
buffer_type
>
buf
)
:
buf_
(
std
::
move
(
buf
)
),
application_cnt_
(
0
)
{
// nop
}
...
...
@@ -112,7 +115,7 @@ public:
}
private:
std
::
shared_ptr
<
std
::
vector
<
byte
>
>
buf_
;
std
::
shared_ptr
<
buffer_type
>
buf_
;
uint8_t
application_cnt_
;
};
...
...
@@ -121,34 +124,35 @@ struct dummy_transport {
using
application_type
=
dummy_application
;
dummy_transport
(
std
::
shared_ptr
<
std
::
vector
<
byte
>>
buf
)
:
buf_
(
buf
)
{
dummy_transport
(
std
::
shared_ptr
<
buffer_type
>
buf
)
:
buf_
(
std
::
move
(
buf
))
{
// nop
}
template
<
class
IdType
>
void
write_packet
(
span
<
const
byte
>
header
,
span
<
const
byte
>
payload
,
IdType
)
{
buf_
->
insert
(
buf_
->
end
(),
header
.
begin
(),
header
.
end
());
buf_
->
insert
(
buf_
->
end
(),
payload
.
begin
(),
payload
.
end
());
void
write_packet
(
IdType
,
span
<
buffer_type
*>
buffers
)
{
for
(
auto
buf
:
buffers
)
buf_
->
insert
(
buf_
->
end
(),
buf
->
begin
(),
buf
->
end
());
}
transport_type
&
transport
()
{
return
*
this
;
}
std
::
vector
<
byte
>
next_buffer
()
{
buffer_type
next_buffer
()
{
return
{};
}
std
::
vector
<
byte
>
next_header_buffer
()
{
buffer_type
next_header_buffer
()
{
return
{};
}
private:
std
::
shared_ptr
<
std
::
vector
<
byte
>
>
buf_
;
std
::
shared_ptr
<
buffer_type
>
buf_
;
};
struct
testdata
{
testdata
(
uint8_t
worker_id
,
node_id
id
,
ip_endpoint
ep
)
:
worker_id
(
worker_id
),
nid
(
id
),
ep
(
ep
)
{
:
worker_id
(
worker_id
),
nid
(
std
::
move
(
id
)
),
ep
(
ep
)
{
// nop
}
...
...
@@ -180,7 +184,7 @@ struct fixture : host_fixture {
ip_endpoint
>
;
fixture
()
:
buf
{
std
::
make_shared
<
std
::
vector
<
byte
>
>
()},
:
buf
{
std
::
make_shared
<
buffer_type
>
()},
dispatcher
{
dummy_application_factory
{
buf
}},
dummy
{
buf
}
{
add_new_workers
();
...
...
@@ -192,7 +196,7 @@ struct fixture : host_fixture {
actor_config
cfg
;
auto
p
=
make_actor
<
dummy_actor
,
strong_actor_ptr
>
(
aid
,
nid
,
&
sys
,
cfg
);
auto
test_span
=
as_bytes
(
make_span
(
hello_test
));
std
::
vector
<
byte
>
payload
(
test_span
.
begin
(),
test_span
.
end
());
buffer_type
payload
(
test_span
.
begin
(),
test_span
.
end
());
auto
strong_actor
=
actor_cast
<
strong_actor_ptr
>
(
p
);
mailbox_element
::
forwarding_stack
stack
;
auto
elem
=
make_mailbox_element
(
std
::
move
(
strong_actor
),
...
...
@@ -225,7 +229,7 @@ struct fixture : host_fixture {
actor_system_config
cfg
{};
actor_system
sys
{
cfg
};
std
::
shared_ptr
<
std
::
vector
<
byte
>
>
buf
;
std
::
shared_ptr
<
buffer_type
>
buf
;
dispatcher_type
dispatcher
;
dummy_transport
dummy
;
...
...
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