Future<Nothing> HealthCheckerProcess::__tcpHealthCheck( const tuple< Future<Option<int>>, Future<string>, Future<string>>& t) { Future<Option<int>> status = std::get<0>(t); if (!status.isReady()) { return Failure( "Failed to get the exit status of the " + string(TCP_CHECK_COMMAND) + " process: " + (status.isFailed() ? status.failure() : "discarded")); } if (status->isNone()) { return Failure( "Failed to reap the " + string(TCP_CHECK_COMMAND) + " process"); } int statusCode = status->get(); if (statusCode != 0) { Future<string> error = std::get<2>(t); if (!error.isReady()) { return Failure( string(TCP_CHECK_COMMAND) + " returned " + WSTRINGIFY(statusCode) + "; reading stderr failed: " + (error.isFailed() ? error.failure() : "discarded")); } return Failure( string(TCP_CHECK_COMMAND) + " returned " + WSTRINGIFY(statusCode) + ": " + error.get()); } return Nothing(); }
void LeaderContenderProcess::cancelled(const Future<bool>& result) { CHECK_READY(candidacy); LOG(INFO) << "Membership cancelled: " << candidacy->id(); // Can be called as a result of either withdraw() or server side // expiration. CHECK(withdrawing.isSome() || watching.isSome()); CHECK(!result.isDiscarded()); if (result.isFailed()) { if (withdrawing.isSome()) { withdrawing.get()->fail(result.failure()); } if (watching.isSome()) { watching.get()->fail(result.failure()); } } else { if (withdrawing.isSome()) { withdrawing.get()->set(result); } if (watching.isSome()) { watching.get()->set(Nothing()); } } }
Future<Nothing> HealthCheckerProcess::__httpHealthCheck( const tuple< Future<Option<int>>, Future<string>, Future<string>>& t) { Future<Option<int>> status = std::get<0>(t); if (!status.isReady()) { return Failure( "Failed to get the exit status of the " + string(HTTP_CHECK_COMMAND) + " process: " + (status.isFailed() ? status.failure() : "discarded")); } if (status->isNone()) { return Failure( "Failed to reap the " + string(HTTP_CHECK_COMMAND) + " process"); } int statusCode = status->get(); if (statusCode != 0) { Future<string> error = std::get<2>(t); if (!error.isReady()) { return Failure( string(HTTP_CHECK_COMMAND) + " returned " + WSTRINGIFY(statusCode) + "; reading stderr failed: " + (error.isFailed() ? error.failure() : "discarded")); } return Failure( string(HTTP_CHECK_COMMAND) + " returned " + WSTRINGIFY(statusCode) + ": " + error.get()); } Future<string> output = std::get<1>(t); if (!output.isReady()) { return Failure( "Failed to read stdout from " + string(HTTP_CHECK_COMMAND) + ": " + (output.isFailed() ? output.failure() : "discarded")); } // Parse the output and get the HTTP response code. Try<int> code = numify<int>(output.get()); if (code.isError()) { return Failure( "Unexpected output from " + string(HTTP_CHECK_COMMAND) + ": " + output.get()); } if (code.get() < process::http::Status::OK || code.get() >= process::http::Status::BAD_REQUEST) { return Failure( "Unexpected HTTP response code: " + process::http::Status::string(code.get())); } return Nothing(); }
Future<Nothing> untar(const string& file, const string& directory) { const vector<string> argv = { "tar", "-C", directory, "-x", "-f", file }; Try<Subprocess> s = subprocess( "tar", argv, Subprocess::PATH("/dev/null"), Subprocess::PATH("/dev/null"), Subprocess::PIPE()); if (s.isError()) { return Failure("Failed to execute the subprocess: " + s.error()); } return await( s.get().status(), process::io::read(s.get().err().get())) .then([](const tuple< Future<Option<int>>, Future<string>>& t) -> Future<Nothing> { Future<Option<int>> status = std::get<0>(t); if (!status.isReady()) { return Failure( "Failed to get the exit status of the subprocess: " + (status.isFailed() ? status.failure() : "discarded")); } Future<string> error = std::get<1>(t); if (!error.isReady()) { return Failure( "Failed to read stderr from the subprocess: " + (error.isFailed() ? error.failure() : "discarded")); } if (status->isNone()) { return Failure("Failed to reap the subprocess"); } if (status->get() != 0) { return Failure( "Unexpected result from the subprocess: " + WSTRINGIFY(status->get()) + ", stderr='" + error.get() + "'"); } return Nothing(); }); }
void LeaderDetectorProcess::watched(Future<set<Group::Membership> > memberships) { CHECK(!memberships.isDiscarded()); if (memberships.isFailed()) { LOG(ERROR) << "Failed to watch memberships: " << memberships.failure(); leader = None(); foreach (Promise<Option<Group::Membership> >* promise, promises) { promise->fail(memberships.failure()); delete promise; }
Future<Nothing> NetworkCniIsolatorProcess::_detach( const ContainerID& containerId, const std::string& networkName, const string& plugin, const tuple<Future<Option<int>>, Future<string>>& t) { CHECK(infos.contains(containerId)); CHECK(infos[containerId]->containerNetworks.contains(networkName)); Future<Option<int>> status = std::get<0>(t); if (!status.isReady()) { return Failure( "Failed to get the exit status of the CNI plugin '" + plugin + "' subprocess: " + (status.isFailed() ? status.failure() : "discarded")); } if (status->isNone()) { return Failure( "Failed to reap the CNI plugin '" + plugin + "' subprocess"); } if (status.get() == 0) { const string ifDir = paths::getInterfaceDir( rootDir.get(), containerId.value(), networkName, infos[containerId]->containerNetworks[networkName].ifName); Try<Nothing> rmdir = os::rmdir(ifDir); if (rmdir.isError()) { return Failure( "Failed to remove interface directory '" + ifDir + "': " + rmdir.error()); } return Nothing(); } // CNI plugin will print result (in case of success) or error (in // case of failure) to stdout. Future<string> output = std::get<1>(t); if (!output.isReady()) { return Failure( "Failed to read stdout from the CNI plugin '" + plugin + "' subprocess: " + (output.isFailed() ? output.failure() : "discarded")); } return Failure( "The CNI plugin '" + plugin + "' failed to detach container " "from network '" + networkName + "': " + output.get()); }
static Future<Nothing> _fetch(const Future<std::tuple< Future<Option<int>>, Future<string>, Future<string>>>& future) { CHECK_READY(future); Future<Option<int>> status = std::get<0>(future.get()); if (!status.isReady()) { return Failure( "Failed to get the exit status of the curl subprocess: " + (status.isFailed() ? status.failure() : "discarded")); } if (status->isNone()) { return Failure("Failed to reap the curl subprocess"); } if (status->get() != 0) { Future<string> error = std::get<2>(future.get()); if (!error.isReady()) { return Failure( "Failed to perform 'curl'. Reading stderr failed: " + (error.isFailed() ? error.failure() : "discarded")); } return Failure("Failed to perform 'curl': " + error.get()); } Future<string> output = std::get<1>(future.get()); if (!output.isReady()) { return Failure( "Failed to read stdout from 'curl': " + (output.isFailed() ? output.failure() : "discarded")); } // Parse the output and get the HTTP response code. Try<int> code = numify<int>(output.get()); if (code.isError()) { return Failure("Unexpected output from 'curl': " + output.get()); } if (code.get() != http::Status::OK) { return Failure( "Unexpected HTTP response code: " + http::Status::string(code.get())); } return Nothing(); }
void RegistrarProcess::_recover( const MasterInfo& info, const Future<Variable<Registry> >& recovery) { updating = false; CHECK(!recovery.isPending()); if (!recovery.isReady()) { recovered.get()->fail("Failed to recover registrar: " + (recovery.isFailed() ? recovery.failure() : "discarded")); } else { Duration elapsed = metrics.state_fetch.stop(); LOG(INFO) << "Successfully fetched the registry" << " (" << Bytes(recovery.get().get().ByteSize()) << ")" << " in " << elapsed; // Save the registry. variable = recovery.get(); // Perform the Recover operation to add the new MasterInfo. Owned<Operation> operation(new Recover(info)); operations.push_back(operation); operation->future() .onAny(defer(self(), &Self::__recover, lambda::_1)); update(); } }
/* * Class: org_apache_mesos_state_ZooKeeperState * Method: __fetch_get * Signature: (J)Lorg/apache/mesos/state/Variable; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1get (JNIEnv* env, jobject thiz, jlong jfuture) { Future<Variable>* future = (Future<Variable>*) jfuture; future->await(); if (future->isFailed()) { jclass clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { jclass clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK(future->isReady()); Variable* variable = new Variable(future->get()); // Variable variable = new Variable(); jclass clazz = env->FindClass("org/apache/mesos/state/Variable"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jvariable = env->NewObject(clazz, _init_); jfieldID __variable = env->GetFieldID(clazz, "__variable", "J"); env->SetLongField(jvariable, __variable, (jlong) variable); return jvariable; }
TEST(HTTPTest, PipeFailure) { http::Pipe pipe; http::Pipe::Reader reader = pipe.reader(); http::Pipe::Writer writer = pipe.writer(); // Fail the writer after writing some data. EXPECT_TRUE(writer.write("hello")); EXPECT_TRUE(writer.write("world")); EXPECT_TRUE(writer.fail("disconnected!")); // The reader should read the data, followed by the failure. AWAIT_EQ("hello", reader.read()); AWAIT_EQ("world", reader.read()); Future<string> read = reader.read(); EXPECT_TRUE(read.isFailed()); EXPECT_EQ("disconnected!", read.failure()); // The writer cannot close or fail an already failed pipe. EXPECT_FALSE(writer.close()); EXPECT_FALSE(writer.fail("not again")); // The writer shouldn't be notified of the reader closing, // since the writer had already failed. EXPECT_TRUE(reader.close()); EXPECT_TRUE(writer.readerClosed().isPending()); }
/* * Class: org_apache_mesos_state_ZooKeeperState * Method: __expunge_get * Signature: (J)Ljava/lang/Boolean; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1expunge_1get (JNIEnv* env, jobject thiz, jlong jfuture) { Future<bool>* future = (Future<bool>*) jfuture; future->await(); if (future->isFailed()) { jclass clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { jclass clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK(future->isReady()); if (future->get()) { jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "TRUE", "Ljava/lang/Boolean;")); } jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "FALSE", "Ljava/lang/Boolean;")); }
void LeaderDetectorProcess::watched(const Future<set<Group::Membership> >& memberships) { CHECK(!memberships.isDiscarded()); if (memberships.isFailed()) { LOG(ERROR) << "Failed to watch memberships: " << memberships.failure(); // Setting this error stops the watch loop and the detector // transitions to an erroneous state. Further calls to detect() // will directly fail as a result. error = Error(memberships.failure()); leader = None(); foreach (Promise<Option<Group::Membership> >* promise, promises) { promise->fail(memberships.failure()); delete promise; }
/* * Class: org_apache_mesos_state_AbstractState * Method: __expunge_get * Signature: (J)Ljava/lang/Boolean; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1expunge_1get (JNIEnv* env, jobject thiz, jlong jfuture) { Future<bool>* future = (Future<bool>*) jfuture; future->await(); if (future->isFailed()) { jclass clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. jclass clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK_READY(*future); if (future->get()) { jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "TRUE", "Ljava/lang/Boolean;")); } jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "FALSE", "Ljava/lang/Boolean;")); }
/* * Class: org_apache_mesos_state_AbstractState * Method: __fetch_get * Signature: (J)Lorg/apache/mesos/state/Variable; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1fetch_1get (JNIEnv* env, jobject thiz, jlong jfuture) { Future<Variable>* future = (Future<Variable>*) jfuture; future->await(); if (future->isFailed()) { jclass clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return nullptr; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. jclass clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return nullptr; } CHECK_READY(*future); Variable* variable = new Variable(future->get()); // Variable variable = new Variable(); jclass clazz = env->FindClass("org/apache/mesos/state/Variable"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jvariable = env->NewObject(clazz, _init_); jfieldID __variable = env->GetFieldID(clazz, "__variable", "J"); env->SetLongField(jvariable, __variable, (jlong) variable); return jvariable; }
TEST(CoordinatorTest, Truncate) { const std::string path1 = utils::os::getcwd() + "/.log1"; const std::string path2 = utils::os::getcwd() + "/.log2"; utils::os::rmdir(path1); utils::os::rmdir(path2); Replica replica1(path1); Replica replica2(path2); Network network; network.add(replica1.pid()); network.add(replica2.pid()); Coordinator coord(2, &replica1, &network); { Result<uint64_t> result = coord.elect(Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(0, result.get()); } for (uint64_t position = 1; position <= 10; position++) { Result<uint64_t> result = coord.append(utils::stringify(position), Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(position, result.get()); } { Result<uint64_t> result = coord.truncate(7, Timeout(1.0)); ASSERT_TRUE(result.isSome()); EXPECT_EQ(11, result.get()); } { Future<std::list<Action> > actions = replica1.read(6, 10); ASSERT_TRUE(actions.await(2.0)); ASSERT_TRUE(actions.isFailed()); EXPECT_EQ("Bad read range (truncated position)", actions.failure()); } { Future<std::list<Action> > actions = replica1.read(7, 10); ASSERT_TRUE(actions.await(2.0)); ASSERT_TRUE(actions.isReady()); EXPECT_EQ(4, actions.get().size()); foreach (const Action& action, actions.get()) { ASSERT_TRUE(action.has_type()); ASSERT_EQ(Action::APPEND, action.type()); EXPECT_EQ(utils::stringify(action.position()), action.append().bytes()); } } utils::os::rmdir(path1); utils::os::rmdir(path2); }
void _healthCheck() { if (check.has_http()) { promise.fail("HTTP health check is not supported"); } else if (check.has_command()) { const CommandInfo& command = check.command(); map<string, string> environment; foreach (const Environment_Variable& variable, command.environment().variables()) { environment[variable.name()] = variable.value(); } VLOG(2) << "Launching health command: " << command.value(); Try<Subprocess> external = process::subprocess( command.value(), // Reading from STDIN instead of PIPE because scripts // seeing an open STDIN pipe might behave differently // and we do not expect to pass any value from STDIN // or PIPE. Subprocess::FD(STDIN_FILENO), Subprocess::FD(STDERR_FILENO), Subprocess::FD(STDERR_FILENO), environment); if (external.isError()) { promise.fail("Error creating subprocess for healthcheck"); } else { Future<Option<int> > status = external.get().status(); status.await(Seconds(check.timeout_seconds())); if (!status.isReady()) { string msg = "Shell command check failed with reason: "; if (status.isFailed()) { msg += "failed with error: " + status.failure(); } else if (status.isDiscarded()) { msg += "status future discarded"; } else { msg += "status still pending after timeout " + stringify(Seconds(check.timeout_seconds())); } promise.fail(msg); return; } int statusCode = status.get().get(); if (statusCode != 0) { string message = "Health command check " + WSTRINGIFY(statusCode); failure(message); } else { success(); } } } else {
Future<Nothing> _destroy(const Future<Option<int>>& future) { if (future.isReady()) { return Nothing(); } else { return Failure("Failed to kill all processes: " + (future.isFailed() ? future.failure() : "unknown error")); } }
TEST_F(CoordinatorTest, Truncate) { const string path1 = os::getcwd() + "/.log1"; initializer.flags.path = path1; initializer.execute(); const string path2 = os::getcwd() + "/.log2"; initializer.flags.path = path2; initializer.execute(); Shared<Replica> replica1(new Replica(path1)); Shared<Replica> replica2(new Replica(path2)); set<UPID> pids; pids.insert(replica1->pid()); pids.insert(replica2->pid()); Shared<Network> network(new Network(pids)); Coordinator coord(2, replica1, network); { Future<Option<uint64_t> > electing = coord.elect(); AWAIT_READY_FOR(electing, Seconds(10)); ASSERT_SOME(electing.get()); EXPECT_EQ(0u, electing.get().get()); } for (uint64_t position = 1; position <= 10; position++) { Future<uint64_t> appending = coord.append(stringify(position)); AWAIT_READY_FOR(appending, Seconds(10)); EXPECT_EQ(position, appending.get()); } { Future<uint64_t> truncating = coord.truncate(7); AWAIT_READY_FOR(truncating, Seconds(10)); EXPECT_EQ(11u, truncating.get()); } { Future<list<Action> > actions = replica1->read(6, 10); AWAIT_FAILED(actions); EXPECT_EQ("Bad read range (truncated position)", actions.failure()); } { Future<list<Action> > actions = replica1->read(7, 10); AWAIT_READY(actions); EXPECT_EQ(4u, actions.get().size()); foreach (const Action& action, actions.get()) { ASSERT_TRUE(action.has_type()); ASSERT_EQ(Action::APPEND, action.type()); EXPECT_EQ(stringify(action.position()), action.append().bytes()); } } }
void reaped( ExecutorDriver* driver, const TaskID& taskId, pid_t pid, const Future<Option<int> >& status_) { TaskState state; string message; Timer::cancel(escalationTimer); if (!status_.isReady()) { state = TASK_FAILED; message = "Failed to get exit status for Command: " + (status_.isFailed() ? status_.failure() : "future discarded"); } else if (status_.get().isNone()) { state = TASK_FAILED; message = "Failed to get exit status for Command"; } else { int status = status_.get().get(); CHECK(WIFEXITED(status) || WIFSIGNALED(status)) << status; if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { state = TASK_FINISHED; } else if (killed) { // Send TASK_KILLED if the task was killed as a result of // killTask() or shutdown(). state = TASK_KILLED; } else { state = TASK_FAILED; } message = string("Command") + (WIFEXITED(status) ? " exited with status " : " terminated with signal ") + (WIFEXITED(status) ? stringify(WEXITSTATUS(status)) : strsignal(WTERMSIG(status))); } cout << message << " (pid: " << pid << ")" << endl; TaskStatus taskStatus; taskStatus.mutable_task_id()->MergeFrom(taskId); taskStatus.set_state(state); taskStatus.set_message(message); driver->sendStatusUpdate(taskStatus); // A hack for now ... but we need to wait until the status update // is sent to the slave before we shut ourselves down. os::sleep(Seconds(1)); driver->stop(); }
/* * Class: org_apache_mesos_state_AbstractState * Method: __names_get_timeout * Signature: (JJLjava/util/concurrent/TimeUnit;)Ljava/util/Iterator; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1names_1get_1timeout (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit) { Future<set<string> >* future = (Future<set<string> >*) jfuture; jclass clazz = env->GetObjectClass(junit); // long seconds = unit.toSeconds(time); jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J"); jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout); Seconds seconds(jseconds); if (future->await(seconds)) { if (future->isFailed()) { clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK_READY(*future); // List names = new ArrayList(); clazz = env->FindClass("java/util/ArrayList"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jnames = env->NewObject(clazz, _init_); jmethodID add = env->GetMethodID(clazz, "add", "(Ljava/lang/Object;)Z"); foreach (const string& name, future->get()) { jobject jname = convert<string>(env, name); env->CallBooleanMethod(jnames, add, jname); } // Iterator iterator = jnames.iterator(); jmethodID iterator = env->GetMethodID(clazz, "iterator", "()Ljava/util/Iterator;"); jobject jiterator = env->CallObjectMethod(jnames, iterator); return jiterator; } clazz = env->FindClass("java/util/concurrent/TimeoutException"); env->ThrowNew(clazz, "Failed to wait for future within timeout"); return NULL; }
void _read(const Pipe::Reader& reader, const Future<Result<Event>>& event) { CHECK(!event.isDiscarded()); // Ignore enqueued events from the previous Subscribe call reader. if (subscribed.isNone() || subscribed->reader != reader) { VLOG(1) << "Ignoring event from old stale connection"; return; } CHECK_EQ(SUBSCRIBED, state); CHECK_SOME(connectionId); // This could happen if the agent process died while sending a response. if (event.isFailed()) { LOG(ERROR) << "Failed to decode the stream of events: " << event.failure(); disconnected(connectionId.get(), event.failure()); return; } // This could happen if the agent failed over after sending an event. if (event->isNone()) { const string error = "End-Of-File received from agent. The agent closed " "the event stream"; LOG(ERROR) << error; disconnected(connectionId.get(), error); return; } if (event->isError()) { error("Failed to de-serialize event: " + event->error()); return; } receive(event.get().get(), false); read(); }
/* * Class: org_apache_mesos_state_AbstractState * Method: __store_get_timeout * Signature: (JJLjava/util/concurrent/TimeUnit;)Lorg/apache/mesos/state/Variable; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1store_1get_1timeout (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit) { Future<Option<Variable> >* future = (Future<Option<Variable> >*) jfuture; jclass clazz = env->GetObjectClass(junit); // long seconds = unit.toSeconds(time); jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J"); jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout); Seconds seconds(jseconds); if (future->await(seconds)) { if (future->isFailed()) { clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK_READY(*future); if (future->get().isSome()) { Variable* variable = new Variable(future->get().get()); // Variable variable = new Variable(); clazz = env->FindClass("org/apache/mesos/state/Variable"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jvariable = env->NewObject(clazz, _init_); jfieldID __variable = env->GetFieldID(clazz, "__variable", "J"); env->SetLongField(jvariable, __variable, (jlong) variable); return jvariable; } return NULL; } clazz = env->FindClass("java/util/concurrent/TimeoutException"); env->ThrowNew(clazz, "Failed to wait for future within timeout"); return NULL; }
// Find out how large a potential download from the given URI is. static Try<Bytes> fetchSize( const string& uri, const Option<string>& frameworksHome) { VLOG(1) << "Fetching size for URI: " << uri; Result<string> path = Fetcher::uriToLocalPath(uri, frameworksHome); if (path.isError()) { return Error(path.error()); } if (path.isSome()) { Try<Bytes> size = os::stat::size(path.get(), os::stat::FOLLOW_SYMLINK); if (size.isError()) { return Error("Could not determine file size for: '" + path.get() + "', error: " + size.error()); } return size.get(); } if (Fetcher::isNetUri(uri)) { Try<Bytes> size = net::contentLength(uri); if (size.isError()) { return Error(size.error()); } if (size.get() == 0) { return Error("URI reported content-length 0: " + uri); } return size.get(); } // TODO(hausdorff): (MESOS-5460) Explore adding support for fetching from // HDFS. #ifndef __WINDOWS__ Try<Owned<HDFS>> hdfs = HDFS::create(); if (hdfs.isError()) { return Error("Failed to create HDFS client: " + hdfs.error()); } Future<Bytes> size = hdfs.get()->du(uri); size.await(); if (!size.isReady()) { return Error("Hadoop client could not determine size: " + (size.isFailed() ? size.failure() : "discarded")); } return size.get(); #else return Error("Windows currently does not support fetching files from HDFS"); #endif // __WINDOWS__ }
TEST(DecoderTest, StreamingResponseFailure) { StreamingResponseDecoder decoder; const string headers = "HTTP/1.1 200 OK\r\n" "Date: Fri, 31 Dec 1999 23:59:59 GMT\r\n" "Content-Type: text/plain\r\n" "Content-Length: 2\r\n" "\r\n"; // The body is shorter than the content length! const string body = "1"; deque<http::Response*> responses = decoder.decode(headers.data(), headers.length()); EXPECT_FALSE(decoder.failed()); EXPECT_TRUE(decoder.writingBody()); ASSERT_EQ(1, responses.size()); Owned<http::Response> response(responses[0]); EXPECT_EQ("200 OK", response->status); EXPECT_EQ(3, response->headers.size()); ASSERT_EQ(http::Response::PIPE, response->type); ASSERT_SOME(response->reader); http::Pipe::Reader reader = response->reader.get(); Future<string> read = reader.read(); EXPECT_TRUE(read.isPending()); decoder.decode(body.data(), body.length()); EXPECT_FALSE(decoder.failed()); EXPECT_TRUE(decoder.writingBody()); EXPECT_TRUE(read.isReady()); EXPECT_EQ("1", read.get()); // Body is not yet complete. read = reader.read(); EXPECT_TRUE(read.isPending()); // Feeding EOF to the decoder should trigger a failure! decoder.decode("", 0); EXPECT_TRUE(decoder.failed()); EXPECT_FALSE(decoder.writingBody()); EXPECT_TRUE(read.isFailed()); EXPECT_EQ("failed to decode body", read.failure()); }
void HealthCheckerProcess::__healthCheck(const Future<Nothing>& future) { if (future.isReady()) { success(); return; } string message = HealthCheck::Type_Name(check.type()) + " health check failed: " + (future.isFailed() ? future.failure() : "discarded"); failure(message); }
// See the comment below as to why subprocess is passed to cleanup. inline void cleanup( const Future<Option<int> >& result, Promise<Option<int> >* promise, const Subprocess& subprocess) { CHECK(!result.isPending()); CHECK(!result.isDiscarded()); if (result.isFailed()) { promise->fail(result.failure()); } else { promise->set(result.get()); } delete promise; }
// Find out how large a potential download from the given URI is. static Try<Bytes> fetchSize( const string& uri, const Option<string>& frameworksHome) { VLOG(1) << "Fetching size for URI: " << uri; Result<string> path = Fetcher::uriToLocalPath(uri, frameworksHome); if (path.isError()) { return Error(path.error()); } if (path.isSome()) { Try<Bytes> size = os::stat::size(path.get(), os::stat::FOLLOW_SYMLINK); if (size.isError()) { return Error("Could not determine file size for: '" + path.get() + "', error: " + size.error()); } return size.get(); } if (Fetcher::isNetUri(uri)) { Try<Bytes> size = net::contentLength(uri); if (size.isError()) { return Error(size.error()); } if (size.get() == 0) { return Error("URI reported content-length 0: " + uri); } return size.get(); } Try<Owned<HDFS>> hdfs = HDFS::create(); if (hdfs.isError()) { return Error("Failed to create HDFS client: " + hdfs.error()); } Future<Bytes> size = hdfs.get()->du(uri); size.await(); if (!size.isReady()) { return Error("Hadoop client could not determine size: " + (size.isFailed() ? size.failure() : "discarded")); } return size.get(); }
void waited(const Future<T>& future) { if (future.isFailed()) { promise->fail("Collect failed: " + future.failure()); terminate(this); } else if (future.isDiscarded()) { promise->fail("Collect failed: future discarded"); terminate(this); } else { assert(future.isReady()); values.push_back(future.get()); if (futures.size() == values.size()) { promise->set(values); terminate(this); } } }
/* * Class: org_apache_mesos_state_AbstractState * Method: __expunge_get_timeout * Signature: (JJLjava/util/concurrent/TimeUnit;)Ljava/lang/Boolean; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_AbstractState__1_1expunge_1get_1timeout (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit) { Future<bool>* future = (Future<bool>*) jfuture; jclass clazz = env->GetObjectClass(junit); // long seconds = unit.toSeconds(time); jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J"); jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout); Seconds seconds(jseconds); if (future->await(seconds)) { if (future->isFailed()) { clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { // TODO(benh): Consider throwing an ExecutionException since we // never return true for 'isCancelled'. clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK_READY(*future); if (future->get()) { jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "TRUE", "Ljava/lang/Boolean;")); } jclass clazz = env->FindClass("java/lang/Boolean"); return env->GetStaticObjectField( clazz, env->GetStaticFieldID(clazz, "FALSE", "Ljava/lang/Boolean;")); } clazz = env->FindClass("java/util/concurrent/TimeoutException"); env->ThrowNew(clazz, "Failed to wait for future within timeout"); return NULL; }
/* * Class: org_apache_mesos_state_ZooKeeperState * Method: __fetch_get_timeout * Signature: (JJLjava/util/concurrent/TimeUnit;)Lorg/apache/mesos/state/Variable; */ JNIEXPORT jobject JNICALL Java_org_apache_mesos_state_ZooKeeperState__1_1fetch_1get_1timeout (JNIEnv* env, jobject thiz, jlong jfuture, jlong jtimeout, jobject junit) { Future<Variable>* future = (Future<Variable>*) jfuture; jclass clazz = env->GetObjectClass(junit); // long seconds = unit.toSeconds(time); jmethodID toSeconds = env->GetMethodID(clazz, "toSeconds", "(J)J"); jlong jseconds = env->CallLongMethod(junit, toSeconds, jtimeout); Seconds seconds(jseconds); if (future->await(seconds)) { if (future->isFailed()) { clazz = env->FindClass("java/util/concurrent/ExecutionException"); env->ThrowNew(clazz, future->failure().c_str()); return NULL; } else if (future->isDiscarded()) { clazz = env->FindClass("java/util/concurrent/CancellationException"); env->ThrowNew(clazz, "Future was discarded"); return NULL; } CHECK(future->isReady()); Variable* variable = new Variable(future->get()); // Variable variable = new Variable(); clazz = env->FindClass("org/apache/mesos/state/Variable"); jmethodID _init_ = env->GetMethodID(clazz, "<init>", "()V"); jobject jvariable = env->NewObject(clazz, _init_); jfieldID __variable = env->GetFieldID(clazz, "__variable", "J"); env->SetLongField(jvariable, __variable, (jlong) variable); return jvariable; } clazz = env->FindClass("java/util/concurrent/TimeoutException"); env->ThrowNew(clazz, "Failed to wait for future within timeout"); return NULL; }