[ https://issues.apache.org/jira/browse/MESOS-1160?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13960555#comment-13960555 ]
Benjamin Mahler commented on MESOS-1160: ---------------------------------------- I was also thinking this would be done via (2) and yes, a subsequent patch for cleanup would be great. > Support flattening from {Try,Result} into Future. > ------------------------------------------------- > > Key: MESOS-1160 > URL: https://issues.apache.org/jira/browse/MESOS-1160 > Project: Mesos > Issue Type: Improvement > Components: libprocess > Reporter: Benjamin Mahler > Labels: newbie > > We should consider adding support for constructing a Future<T> from a Try<T>, > the flattening is rather straightforward: > * Try is SOME, then Future is READY. > * Try is ERROR, then Future is FAILED. > Ideally we should consider consolidating terminology (Error vs. Failed / > Failure) as well, but the flattening in itself is beneficial. > Consider the following code: > {code} > void Slave::checkDiskUsage() > { > // TODO(vinod): We are making usage a Future, so that we can plug in > // fs::usage() into async. > Future<Try<double> >(fs::usage(flags.work_dir)) > .onAny(defer(self(), &Slave::_checkDiskUsage, lambda::_1)); > } > void Slave::_checkDiskUsage(const Future<Try<double> >& usage) > { > if (!usage.isReady()) { > LOG(ERROR) << "Failed to get disk usage: " > << (usage.isFailed() ? usage.failure() : "future discarded"); > } else { > Try<double> result = usage.get(); > if (result.isSome()) { > double use = result.get(); > LOG(INFO) << "Current usage " << std::setiosflags(std::ios::fixed) > << std::setprecision(2) << 100 * use << "%." > << " Max allowed age: " << age(use); > // We prune all directories whose deletion time is within > // the next 'gc_delay - age'. Since a directory is always > // scheduled for deletion 'gc_delay' into the future, only directories > // that are at least 'age' old are deleted. > gc.prune(flags.gc_delay - age(use)); > } else { > LOG(WARNING) << "Unable to get disk usage: " << result.error(); > } > } > delay(flags.disk_watch_interval, self(), &Slave::checkDiskUsage); > } > {code} > With flattening this code becomes: > {code} > void Slave::checkDiskUsage() > { > // TODO(vinod): We are making usage a Future, so that we can plug in > // fs::usage() into async. > Future<double>(fs::usage(flags.work_dir)) > .onAny(defer(self(), &Slave::_checkDiskUsage, lambda::_1)); > } > void Slave::_checkDiskUsage(const Future<double>& usage) > { > if (!usage.isReady()) { > LOG(WARNING) << "Failed to get disk usage: " > << (usage.isFailed() ? usage.failure() : "future discarded"); > } else { > LOG(INFO) << "Current usage " << std::setiosflags(std::ios::fixed) > << std::setprecision(2) << 100 * usage.get() << "%." > << " Max allowed age: " << age(usage.get()); > // We prune all directories whose deletion time is within > // the next 'gc_delay - age'. Since a directory is always > // scheduled for deletion 'gc_delay' into the future, only directories > // that are at least 'age' old are deleted. > gc.prune(flags.gc_delay - age(usage.get())); > } > delay(flags.disk_watch_interval, self(), &Slave::checkDiskUsage); > } > {code} > For Result, the conversion is a bit less clear but logically a Result<T> maps > to a Future<Option<T> >: > * Result is SOME, then Future is READY and Option is SOME. > * Result is NONE, then Future is READY and Option is NONE. > * Result is ERROR, then Future is FAILED. -- This message was sent by Atlassian JIRA (v6.2#6252)