Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
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
Operations
Operations
Metrics
Environments
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 Framework
Commits
0f1831cd
Commit
0f1831cd
authored
Dec 02, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve error reporting on function-based actors
parent
0b9b191e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
111 additions
and
32 deletions
+111
-32
libcaf_core/caf/actor_marker.hpp
libcaf_core/caf/actor_marker.hpp
+6
-0
libcaf_core/caf/actor_system.hpp
libcaf_core/caf/actor_system.hpp
+35
-24
libcaf_core/caf/detail/spawnable.hpp
libcaf_core/caf/detail/spawnable.hpp
+38
-0
libcaf_core/caf/detail/type_traits.hpp
libcaf_core/caf/detail/type_traits.hpp
+4
-0
libcaf_core/caf/infer_handle.hpp
libcaf_core/caf/infer_handle.hpp
+2
-2
libcaf_core/caf/local_actor.hpp
libcaf_core/caf/local_actor.hpp
+11
-4
libcaf_io/caf/io/middleman.hpp
libcaf_io/caf/io/middleman.hpp
+7
-1
libcaf_io/caf/io/typed_broker.hpp
libcaf_io/caf/io/typed_broker.hpp
+8
-1
No files found.
libcaf_core/caf/actor_marker.hpp
View file @
0f1831cd
...
@@ -40,5 +40,11 @@ struct actor_marker<behavior> {
...
@@ -40,5 +40,11 @@ struct actor_marker<behavior> {
using
type
=
dynamically_typed_actor_base
;
using
type
=
dynamically_typed_actor_base
;
};
};
template
<
class
T
>
using
is_statically_typed
=
std
::
is_base_of
<
statically_typed_actor_base
,
T
>
;
template
<
class
T
>
using
is_dynamically_typed
=
std
::
is_base_of
<
dynamically_typed_actor_base
,
T
>
;
}
// namespace caf
}
// namespace caf
libcaf_core/caf/actor_system.hpp
View file @
0f1831cd
...
@@ -32,10 +32,12 @@
...
@@ -32,10 +32,12 @@
#include "caf/actor_cast.hpp"
#include "caf/actor_cast.hpp"
#include "caf/actor_clock.hpp"
#include "caf/actor_clock.hpp"
#include "caf/actor_config.hpp"
#include "caf/actor_config.hpp"
#include "caf/actor_marker.hpp"
#include "caf/actor_registry.hpp"
#include "caf/actor_registry.hpp"
#include "caf/composable_behavior_based_actor.hpp"
#include "caf/composable_behavior_based_actor.hpp"
#include "caf/detail/init_fun_factory.hpp"
#include "caf/detail/init_fun_factory.hpp"
#include "caf/detail/spawn_fwd.hpp"
#include "caf/detail/spawn_fwd.hpp"
#include "caf/detail/spawnable.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/group_manager.hpp"
#include "caf/group_manager.hpp"
#include "caf/infer_handle.hpp"
#include "caf/infer_handle.hpp"
...
@@ -328,30 +330,27 @@ public:
...
@@ -328,30 +330,27 @@ public:
return
spawn
<
composable_behavior_based_actor
<
S
>
,
Os
>
();
return
spawn
<
composable_behavior_based_actor
<
S
>
,
Os
>
();
}
}
/// Called by `spawn
_functor` to apply static assertions and
/// Called by `spawn
` when used to create a functor-based actor to select a
///
store an initialization function in `cfg` before calling `spawn_class
`.
///
proper implementation and then delegates to `spawn_impl
`.
/// @param cfg To-be-filled config for the actor.
/// @param cfg To-be-filled config for the actor.
/// @param fun Function object for the actor's behavior; will be moved.
/// @param fun Function object for the actor's behavior; will be moved.
/// @param xs Arguments for `fun`.
/// @param xs Arguments for `fun`.
template
<
spawn_options
Os
,
class
C
,
class
F
,
class
...
Ts
>
/// @private
infer_handle_from_class_t
<
C
>
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
spawn_functor_impl
(
actor_config
&
cfg
,
F
&
fun
,
Ts
&&
...
xs
)
{
infer_handle_from_fun_t
<
F
>
spawn_functor
(
std
::
true_type
,
actor_config
&
cfg
,
detail
::
init_fun_factory
<
C
,
F
>
fac
;
F
&
fun
,
Ts
&&
...
xs
)
{
using
impl
=
infer_impl_from_fun_t
<
F
>
;
detail
::
init_fun_factory
<
impl
,
F
>
fac
;
cfg
.
init_fun
=
fac
(
std
::
move
(
fun
),
std
::
forward
<
Ts
>
(
xs
)...);
cfg
.
init_fun
=
fac
(
std
::
move
(
fun
),
std
::
forward
<
Ts
>
(
xs
)...);
return
spawn_impl
<
C
,
Os
>
(
cfg
);
return
spawn_impl
<
impl
,
Os
>
(
cfg
);
}
}
/// Called by `spawn` when used to create a functor-based actor to select
/// Fallback no-op overload.
/// a proper implementation and then delegates to `spawn_functor_impl`.
/// @private
/// Should not be called by users of the library directly.
/// @param cfg To-be-filled config for the actor.
/// @param fun Function object for the actor's behavior; will be moved.
/// @param xs Arguments for `fun`.
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
infer_handle_from_fun_t
<
F
>
infer_handle_from_fun_t
<
F
>
spawn_functor
(
std
::
false_type
,
actor_config
&
,
F
&
,
spawn_functor
(
actor_config
&
cfg
,
F
&
fun
,
Ts
&&
...
xs
)
{
Ts
&&
...)
{
using
impl
=
infer_impl_from_fun_t
<
F
>
;
return
{};
return
spawn_functor_impl
<
Os
,
impl
>
(
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
}
}
/// Returns a new functor-based actor. The first argument must be the functor,
/// Returns a new functor-based actor. The first argument must be the functor,
...
@@ -361,9 +360,14 @@ public:
...
@@ -361,9 +360,14 @@ public:
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
infer_handle_from_fun_t
<
F
>
infer_handle_from_fun_t
<
F
>
spawn
(
F
fun
,
Ts
&&
...
xs
)
{
spawn
(
F
fun
,
Ts
&&
...
xs
)
{
check_invariants
<
infer_impl_from_fun_t
<
F
>>
();
using
impl
=
infer_impl_from_fun_t
<
F
>
;
check_invariants
<
impl
>
();
static
constexpr
bool
spawnable
=
detail
::
spawnable
<
F
,
impl
,
Ts
...
>
();
static_assert
(
spawnable
,
"cannot spawn function-based actor with given arguments"
);
actor_config
cfg
;
actor_config
cfg
;
return
spawn_functor
<
Os
>
(
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
return
spawn_functor
<
Os
>
(
detail
::
bool_token
<
spawnable
>
{},
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
}
}
/// Returns a new actor with run-time type `name`, constructed
/// Returns a new actor with run-time type `name`, constructed
...
@@ -393,7 +397,7 @@ public:
...
@@ -393,7 +397,7 @@ public:
infer_handle_from_class_t
<
T
>
infer_handle_from_class_t
<
T
>
spawn_class_in_groups
(
actor_config
&
cfg
,
Iter
first
,
Iter
last
,
Ts
&&
...
xs
)
{
spawn_class_in_groups
(
actor_config
&
cfg
,
Iter
first
,
Iter
last
,
Ts
&&
...
xs
)
{
static_assert
(
std
::
is_same
<
infer_handle_from_class_t
<
T
>
,
actor
>::
value
,
static_assert
(
std
::
is_same
<
infer_handle_from_class_t
<
T
>
,
actor
>::
value
,
"
Only dynamically typed actors can be spawned in a group.
"
);
"
only dynamically-typed actors can be spawned in a group
"
);
check_invariants
<
T
>
();
check_invariants
<
T
>
();
auto
irange
=
make_input_range
(
first
,
last
);
auto
irange
=
make_input_range
(
first
,
last
);
cfg
.
groups
=
&
irange
;
cfg
.
groups
=
&
irange
;
...
@@ -407,12 +411,19 @@ public:
...
@@ -407,12 +411,19 @@ public:
infer_handle_from_fun_t
<
F
>
infer_handle_from_fun_t
<
F
>
spawn_fun_in_groups
(
actor_config
&
cfg
,
Iter
first
,
Iter
second
,
spawn_fun_in_groups
(
actor_config
&
cfg
,
Iter
first
,
Iter
second
,
F
&
fun
,
Ts
&&
...
xs
)
{
F
&
fun
,
Ts
&&
...
xs
)
{
static_assert
(
std
::
is_same
<
infer_handle_from_fun_t
<
F
>
,
actor
>::
value
,
using
impl
=
infer_impl_from_fun_t
<
F
>
;
"Only dynamically actors can be spawned in a group."
);
check_invariants
<
impl
>
();
check_invariants
<
infer_impl_from_fun_t
<
F
>>
();
static
constexpr
bool
dynamically_typed
=
is_dynamically_typed
<
impl
>::
value
;
static_assert
(
dynamically_typed
,
"only dynamically-typed actors can join groups"
);
static
constexpr
bool
spawnable
=
detail
::
spawnable
<
F
,
impl
,
Ts
...
>
();
static_assert
(
spawnable
,
"cannot spawn function-based actor with given arguments"
);
static
constexpr
bool
enabled
=
dynamically_typed
&&
spawnable
;
auto
irange
=
make_input_range
(
first
,
second
);
auto
irange
=
make_input_range
(
first
,
second
);
cfg
.
groups
=
&
irange
;
cfg
.
groups
=
&
irange
;
return
spawn_functor
<
Os
>
(
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
return
spawn_functor
<
Os
>
(
detail
::
bool_token
<
enabled
>
{},
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
}
}
/// Returns a new functor-based actor subscribed to all groups in `gs`.
/// Returns a new functor-based actor subscribed to all groups in `gs`.
...
...
libcaf_core/caf/detail/spawnable.hpp
0 → 100644
View file @
0f1831cd
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <type_traits>
#include "caf/detail/type_traits.hpp"
#include "caf/infer_handle.hpp"
namespace
caf
{
namespace
detail
{
/// Returns whether the function object `F` is spawnable from the actor
/// implementation `Impl` with arguments of type `Ts...`.
template
<
class
F
,
class
Impl
,
class
...
Ts
>
constexpr
bool
spawnable
()
{
return
is_callable_with
<
F
,
Ts
...
>::
value
||
is_callable_with
<
F
,
Impl
*
,
Ts
...
>::
value
;
}
}
// namespace detail
}
// namespace caf
libcaf_core/caf/detail/type_traits.hpp
View file @
0f1831cd
...
@@ -694,6 +694,10 @@ struct is_same_ish
...
@@ -694,6 +694,10 @@ struct is_same_ish
is_equal_int_type
<
T
,
U
>
is_equal_int_type
<
T
,
U
>
>::
type
{
};
>::
type
{
};
/// Utility for fallbacks calling `static_assert`.
template
<
class
>
struct
always_false
:
std
::
false_type
{};
}
// namespace detail
}
// namespace detail
}
// namespace caf
}
// namespace caf
libcaf_core/caf/infer_handle.hpp
View file @
0f1831cd
...
@@ -114,8 +114,8 @@ struct infer_handle_from_fun {
...
@@ -114,8 +114,8 @@ struct infer_handle_from_fun {
};
};
/// @relates infer_handle_from_fun
/// @relates infer_handle_from_fun
template
<
class
T
>
template
<
class
F
>
using
infer_handle_from_fun_t
=
typename
infer_handle_from_fun
<
T
>::
type
;
using
infer_handle_from_fun_t
=
typename
infer_handle_from_fun
<
F
>::
type
;
/// @relates infer_handle_from_fun
/// @relates infer_handle_from_fun
template
<
class
T
>
template
<
class
T
>
...
...
libcaf_core/caf/local_actor.hpp
View file @
0f1831cd
...
@@ -34,6 +34,8 @@
...
@@ -34,6 +34,8 @@
#include "caf/behavior.hpp"
#include "caf/behavior.hpp"
#include "caf/check_typed_input.hpp"
#include "caf/check_typed_input.hpp"
#include "caf/delegated.hpp"
#include "caf/delegated.hpp"
#include "caf/detail/type_traits.hpp"
#include "caf/detail/typed_actor_util.hpp"
#include "caf/duration.hpp"
#include "caf/duration.hpp"
#include "caf/error.hpp"
#include "caf/error.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
...
@@ -49,8 +51,6 @@
...
@@ -49,8 +51,6 @@
#include "caf/typed_actor.hpp"
#include "caf/typed_actor.hpp"
#include "caf/typed_response_promise.hpp"
#include "caf/typed_response_promise.hpp"
#include "caf/detail/typed_actor_util.hpp"
namespace
caf
{
namespace
caf
{
/// Base class for actors running on this node, either
/// Base class for actors running on this node, either
...
@@ -109,9 +109,16 @@ public:
...
@@ -109,9 +109,16 @@ public:
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
template
<
spawn_options
Os
=
no_spawn_options
,
class
F
,
class
...
Ts
>
infer_handle_from_fun_t
<
F
>
spawn
(
F
fun
,
Ts
&&
...
xs
)
{
infer_handle_from_fun_t
<
F
>
spawn
(
F
fun
,
Ts
&&
...
xs
)
{
using
impl
=
infer_impl_from_fun_t
<
F
>
;
static
constexpr
bool
spawnable
=
detail
::
spawnable
<
F
,
impl
,
Ts
...
>
();
static_assert
(
spawnable
,
"cannot spawn function-based actor with given arguments"
);
actor_config
cfg
{
context
()};
actor_config
cfg
{
context
()};
return
eval_opts
(
Os
,
system
().
spawn_functor
<
make_unbound
(
Os
)
>
(
static
constexpr
spawn_options
unbound
=
make_unbound
(
Os
);
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...));
detail
::
bool_token
<
spawnable
>
enabled
;
return
eval_opts
(
Os
,
system
().
spawn_functor
<
unbound
>
(
enabled
,
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...));
}
}
template
<
class
T
,
spawn_options
Os
=
no_spawn_options
,
class
Groups
,
template
<
class
T
,
spawn_options
Os
=
no_spawn_options
,
class
Groups
,
...
...
libcaf_io/caf/io/middleman.hpp
View file @
0f1831cd
...
@@ -255,8 +255,14 @@ public:
...
@@ -255,8 +255,14 @@ public:
class
F
=
std
::
function
<
void
(
broker
*
)>,
class
...
Ts
>
class
F
=
std
::
function
<
void
(
broker
*
)>,
class
...
Ts
>
typename
infer_handle_from_fun
<
F
>::
type
typename
infer_handle_from_fun
<
F
>::
type
spawn_broker
(
F
fun
,
Ts
&&
...
xs
)
{
spawn_broker
(
F
fun
,
Ts
&&
...
xs
)
{
using
impl
=
infer_impl_from_fun_t
<
F
>
;
static
constexpr
bool
spawnable
=
detail
::
spawnable
<
F
,
impl
,
Ts
...
>
();
static_assert
(
spawnable
,
"cannot spawn function-based broker with given arguments"
);
actor_config
cfg
{
&
backend
()};
actor_config
cfg
{
&
backend
()};
return
system
().
spawn_functor
<
Os
>
(
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
detail
::
bool_token
<
spawnable
>
enabled
;
return
system
().
spawn_functor
<
Os
>
(
enabled
,
cfg
,
fun
,
std
::
forward
<
Ts
>
(
xs
)...);
}
}
/// Returns a new functor-based broker connected
/// Returns a new functor-based broker connected
...
...
libcaf_io/caf/io/typed_broker.hpp
View file @
0f1831cd
...
@@ -119,7 +119,14 @@ public:
...
@@ -119,7 +119,14 @@ public:
actor_config
cfg
{
this
->
context
()};
actor_config
cfg
{
this
->
context
()};
detail
::
init_fun_factory
<
impl
,
F
>
fac
;
detail
::
init_fun_factory
<
impl
,
F
>
fac
;
cfg
.
init_fun
=
fac
(
std
::
move
(
fun
),
hdl
,
std
::
forward
<
Ts
>
(
xs
)...);
cfg
.
init_fun
=
fac
(
std
::
move
(
fun
),
hdl
,
std
::
forward
<
Ts
>
(
xs
)...);
auto
res
=
this
->
system
().
spawn_functor
(
cfg
,
fun
,
hdl
,
std
::
forward
<
Ts
>
(
xs
)...);
using
impl
=
infer_impl_from_fun_t
<
F
>
;
static
constexpr
bool
spawnable
=
detail
::
spawnable
<
F
,
impl
,
decltype
(
hdl
),
Ts
...
>
();
static_assert
(
spawnable
,
"cannot spawn function-based broker with given arguments"
);
detail
::
bool_token
<
spawnable
>
enabled
;
auto
res
=
this
->
system
().
spawn_functor
(
enabled
,
cfg
,
fun
,
hdl
,
std
::
forward
<
Ts
>
(
xs
)...);
auto
forked
=
static_cast
<
impl
*>
(
actor_cast
<
abstract_actor
*>
(
res
));
auto
forked
=
static_cast
<
impl
*>
(
actor_cast
<
abstract_actor
*>
(
res
));
forked
->
move_scribe
(
std
::
move
(
sptr
));
forked
->
move_scribe
(
std
::
move
(
sptr
));
return
res
;
return
res
;
...
...
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