[
https://issues.apache.org/jira/browse/MESOS-785?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Benjamin Mahler updated MESOS-785:
----------------------------------
Description:
Motivating example was fetching a list of URIs where each 'fetch' is actually a
sequence of operations: fetch the uri to a local file, pass the local file on
to chmod or extract, and pass on to chown it or the directory. Individual
operations needn't be asynchronous.
This can be written using Futures but is potentially confusing when the code is
actually synchronous.
{code}
Future<Nothing> fetch(
const CommandInfo& commandInfo,
const string& directory,
const HDFS& hdfs,
const Option<string>& frameworks_home,
const Option<string>& user)
{
foreach (const CommandInfo::URI& uri, commandInfo.uris()) {
bool executable = uri.has_executable() && uri.executable();
// This code is synchronous!
Future<string> result =
_fetch(uri, directory, hdfs, frameworks_home)
.then(lambda::bind(_chmod, lambda::_1, directory, executable))
.then(lambda::bind(_extract, lambda::_1, directory, !executable))
.then(lambda::bind(_chown, lambda::_1, directory, user));
if (result.isFailed()) {
LOG(ERROR) << "Fetch of uri '" << uri.value() << "' failed: " <<
result.failure();
return Future<Nothing>::failed(result.failure());
}
}
return Nothing();
}
{code}
[~bmahler] and I had these thoughts:
* .ifSome() and .ifError() to express control flow.
* .and() for chaining to make it clear the code is synchronous and also that it
will short-circuit error.
e.g.
{code}
Try<string> result =
_fetch(...)
.and(chmod...)
.and(extract...)
.and(chown...);
{code}
Thoughts? How do other languages express this?
was:
Motivating example was fetching a list of URIs where each 'fetch' is actually a
sequence of operations: fetch the uri to a local file, pass the local file on
to chmod or extract, and pass on to chown it or the directory. Individual
operations needn't be asynchronous.
This can be written using Futures but is potentially confusing when the code is
actually synchronous.
Future<Nothing> fetch(
const CommandInfo& commandInfo,
const string& directory,
const HDFS& hdfs,
const Option<string>& frameworks_home,
const Option<string>& user)
{
foreach (const CommandInfo::URI& uri, commandInfo.uris()) {
bool executable = uri.has_executable() && uri.executable();
// This code is synchronous!
Future<string> result =
_fetch(uri, directory, hdfs, frameworks_home)
.then(lambda::bind(_chmod, lambda::_1, directory, executable))
.then(lambda::bind(_extract, lambda::_1, directory, !executable))
.then(lambda::bind(_chown, lambda::_1, directory, user));
if (result.isFailed()) {
LOG(ERROR) << "Fetch of uri '" << uri.value() << "' failed: " <<
result.failure();
return Future<Nothing>::failed(result.failure());
}
}
return Nothing();
}
[~bmahler] and I had these thoughts:
* .ifSome() and .ifError() to express control flow.
* .and() for chaining to make it clear the code is synchronous and also that it
will short-circuit error.
e.g.
Try<string> result =
_fetch(...)
.and(chmod...)
.and(extract...)
.and(chown...);
Thoughts? How do other languages express this?
> Extend stout/try to support functional composition
> --------------------------------------------------
>
> Key: MESOS-785
> URL: https://issues.apache.org/jira/browse/MESOS-785
> Project: Mesos
> Issue Type: Improvement
> Components: stout
> Reporter: Ian Downes
> Priority: Minor
> Labels: c++11
>
> Motivating example was fetching a list of URIs where each 'fetch' is actually
> a sequence of operations: fetch the uri to a local file, pass the local file
> on to chmod or extract, and pass on to chown it or the directory. Individual
> operations needn't be asynchronous.
> This can be written using Futures but is potentially confusing when the code
> is actually synchronous.
> {code}
> Future<Nothing> fetch(
> const CommandInfo& commandInfo,
> const string& directory,
> const HDFS& hdfs,
> const Option<string>& frameworks_home,
> const Option<string>& user)
> {
> foreach (const CommandInfo::URI& uri, commandInfo.uris()) {
> bool executable = uri.has_executable() && uri.executable();
> // This code is synchronous!
> Future<string> result =
> _fetch(uri, directory, hdfs, frameworks_home)
> .then(lambda::bind(_chmod, lambda::_1, directory, executable))
> .then(lambda::bind(_extract, lambda::_1, directory, !executable))
> .then(lambda::bind(_chown, lambda::_1, directory, user));
> if (result.isFailed()) {
> LOG(ERROR) << "Fetch of uri '" << uri.value() << "' failed: " <<
> result.failure();
> return Future<Nothing>::failed(result.failure());
> }
> }
> return Nothing();
> }
> {code}
> [~bmahler] and I had these thoughts:
> * .ifSome() and .ifError() to express control flow.
> * .and() for chaining to make it clear the code is synchronous and also that
> it will short-circuit error.
> e.g.
> {code}
> Try<string> result =
> _fetch(...)
> .and(chmod...)
> .and(extract...)
> .and(chown...);
> {code}
> Thoughts? How do other languages express this?
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)