Merge branch 'release-5.0' of github.com:apple/foundationdb into release-5.0
This commit is contained in:
commit
dd635cb264
|
@ -213,8 +213,9 @@ public:
|
|||
//If we are in the process of deleting a file, we can't let someone else modify it at the same time. We therefore block the creation of new files until deletion is complete
|
||||
state std::map<std::string, Future<Void>>::iterator deletedFile = filesBeingDeleted.find(filename);
|
||||
if(deletedFile != filesBeingDeleted.end()) {
|
||||
//TraceEvent("AsyncFileNonDurableOpenWaitOnDelete").detail("Filename", filename);
|
||||
//TraceEvent("AsyncFileNonDurableOpenWaitOnDelete1").detail("Filename", filename);
|
||||
Void _ = wait( deletedFile->second || shutdown );
|
||||
//TraceEvent("AsyncFileNonDurableOpenWaitOnDelete2").detail("Filename", filename);
|
||||
if(shutdown.isReady())
|
||||
throw io_error().asInjectedFault();
|
||||
}
|
||||
|
@ -711,35 +712,44 @@ private:
|
|||
|
||||
//Finishes all outstanding actors on an AsyncFileNonDurable and then deletes it
|
||||
ACTOR Future<Void> deleteFile(AsyncFileNonDurable *self) {
|
||||
//We must run on the main thread (instead of a SQLite coroutine). We don't want to signal any promises from a coroutine, so we switch at the beginning
|
||||
//of this ACTOR
|
||||
Void _ = wait(self->returnToMainThread());
|
||||
state ISimulator::ProcessInfo* currentProcess = g_simulator.getCurrentProcess();
|
||||
state int currentTaskID = g_network->getCurrentTask();
|
||||
state std::string filename = self->filename;
|
||||
|
||||
//Make sure all writes have gone through.
|
||||
Promise<bool> startSyncPromise = self->startSyncPromise;
|
||||
self->startSyncPromise = Promise<bool>();
|
||||
startSyncPromise.send(true);
|
||||
Void _ = wait( g_simulator.onMachine( currentProcess ) );
|
||||
try {
|
||||
//Make sure all writes have gone through.
|
||||
Promise<bool> startSyncPromise = self->startSyncPromise;
|
||||
self->startSyncPromise = Promise<bool>();
|
||||
startSyncPromise.send(true);
|
||||
|
||||
std::vector<Future<Void>> outstandingModifications;
|
||||
std::vector<Future<Void>> outstandingModifications;
|
||||
|
||||
for(auto itr = self->pendingModifications.ranges().begin(); itr != self->pendingModifications.ranges().end(); ++itr)
|
||||
if(itr->value().isValid() && !itr->value().isReady())
|
||||
outstandingModifications.push_back(itr->value());
|
||||
for(auto itr = self->pendingModifications.ranges().begin(); itr != self->pendingModifications.ranges().end(); ++itr)
|
||||
if(itr->value().isValid() && !itr->value().isReady())
|
||||
outstandingModifications.push_back(itr->value());
|
||||
|
||||
//Ignore errors here so that all modifications can finish
|
||||
Void _ = wait(waitForAllReady(outstandingModifications));
|
||||
//Ignore errors here so that all modifications can finish
|
||||
Void _ = wait(waitForAllReady(outstandingModifications));
|
||||
|
||||
//Make sure we aren't in the process of killing the file
|
||||
if(self->killed.isSet())
|
||||
Void _ = wait(self->killComplete.getFuture());
|
||||
//Make sure we aren't in the process of killing the file
|
||||
if(self->killed.isSet())
|
||||
Void _ = wait(self->killComplete.getFuture());
|
||||
|
||||
//Remove this file from the filesBeingDeleted map so that new files can be created with this filename
|
||||
g_simulator.getMachineByNetworkAddress( self->openedAddress )->closingFiles.erase(self->getFilename());
|
||||
AsyncFileNonDurable::filesBeingDeleted.erase(self->filename);
|
||||
//TraceEvent("AsyncFileNonDurable_FinishDelete", self->id).detail("Filename", self->filename);
|
||||
//Remove this file from the filesBeingDeleted map so that new files can be created with this filename
|
||||
g_simulator.getMachineByNetworkAddress( self->openedAddress )->closingFiles.erase(self->getFilename());
|
||||
g_simulator.getMachineByNetworkAddress( self->openedAddress )->deletingFiles.erase(self->getFilename());
|
||||
AsyncFileNonDurable::filesBeingDeleted.erase(self->filename);
|
||||
//TraceEvent("AsyncFileNonDurable_FinishDelete", self->id).detail("Filename", self->filename);
|
||||
|
||||
delete self;
|
||||
return Void();
|
||||
delete self;
|
||||
Void _ = wait( g_simulator.onProcess( currentProcess, currentTaskID ) );
|
||||
return Void();
|
||||
} catch( Error &e ) {
|
||||
state Error err = e;
|
||||
Void _ = wait( g_simulator.onProcess( currentProcess, currentTaskID ) );
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -886,16 +886,29 @@ public:
|
|||
// This is a _rudimentary_ simulation of the untrustworthiness of non-durable deletes and the possibility of
|
||||
// rebooting during a durable one. It isn't perfect: for example, on real filesystems testing
|
||||
// for the existence of a non-durably deleted file BEFORE a reboot will show that it apparently doesn't exist.
|
||||
g_simulator.getCurrentProcess()->machine->openFiles.erase(filename);
|
||||
if(g_simulator.getCurrentProcess()->machine->openFiles.count(filename)) {
|
||||
g_simulator.getCurrentProcess()->machine->openFiles.erase(filename);
|
||||
g_simulator.getCurrentProcess()->machine->deletingFiles.insert(filename);
|
||||
}
|
||||
if ( mustBeDurable || g_random->random01() < 0.5 ) {
|
||||
Void _ = wait( ::delay(0.05 * g_random->random01()) );
|
||||
if (!self->getCurrentProcess()->rebooting) {
|
||||
auto f = IAsyncFileSystem::filesystem(self->net2)->deleteFile(filename, false);
|
||||
ASSERT( f.isReady() );
|
||||
state ISimulator::ProcessInfo* currentProcess = g_simulator.getCurrentProcess();
|
||||
state int currentTaskID = g_network->getCurrentTask();
|
||||
Void _ = wait( g_simulator.onMachine( currentProcess ) );
|
||||
try {
|
||||
Void _ = wait( ::delay(0.05 * g_random->random01()) );
|
||||
TEST( true ); // Simulated durable delete
|
||||
if (!currentProcess->rebooting) {
|
||||
auto f = IAsyncFileSystem::filesystem(self->net2)->deleteFile(filename, false);
|
||||
ASSERT( f.isReady() );
|
||||
Void _ = wait( ::delay(0.05 * g_random->random01()) );
|
||||
TEST( true ); // Simulated durable delete
|
||||
}
|
||||
Void _ = wait( g_simulator.onProcess( currentProcess, currentTaskID ) );
|
||||
return Void();
|
||||
} catch( Error &e ) {
|
||||
state Error err = e;
|
||||
Void _ = wait( g_simulator.onProcess( currentProcess, currentTaskID ) );
|
||||
throw err;
|
||||
}
|
||||
return Void();
|
||||
} else {
|
||||
TEST( true ); // Simulated non-durable delete
|
||||
return Void();
|
||||
|
|
|
@ -108,6 +108,7 @@ public:
|
|||
ProcessInfo* machineProcess;
|
||||
std::vector<ProcessInfo*> processes;
|
||||
std::map<std::string, Future<Reference<IAsyncFile>>> openFiles;
|
||||
std::set<std::string> deletingFiles;
|
||||
std::set<std::string> closingFiles;
|
||||
Optional<Standalone<StringRef>> zoneId;
|
||||
|
||||
|
|
|
@ -419,8 +419,8 @@ public:
|
|||
}
|
||||
|
||||
if( error.code() != error_code_actor_cancelled ) {
|
||||
if (!self->stopped.isSet()) self->stopped.send(Void());
|
||||
if (!self->error.isSet()) self->error.send(Never());
|
||||
if (self->stopped.canBeSet()) self->stopped.send(Void());
|
||||
if (self->error.canBeSet()) self->error.send(Never());
|
||||
delete self;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -442,6 +442,11 @@ ACTOR Future<Void> simulatedMachine(
|
|||
ASSERT( it.second.isReady() && !it.second.isError() );
|
||||
}
|
||||
|
||||
for( auto it : g_simulator.getMachineById(localities.zoneId())->deletingFiles ) {
|
||||
filenames.insert( it );
|
||||
closingStr += it + ", ";
|
||||
}
|
||||
|
||||
TraceEvent("SimulatedMachineRebootAfterKills")
|
||||
.detail("Folder0", myFolders[0])
|
||||
.detail("CFolder0", coordFolders[0])
|
||||
|
|
|
@ -1745,7 +1745,7 @@ ACTOR Future<Void> tLog( IKeyValueStore* persistentData, IDiskQueue* persistentQ
|
|||
}
|
||||
}
|
||||
} catch (Error& e) {
|
||||
TraceEvent("TLogError", tlogId).error(e);
|
||||
TraceEvent("TLogError", tlogId).error(e, true);
|
||||
while(!tlogRequests.isEmpty()) {
|
||||
tlogRequests.getFuture().pop().reply.sendError(recruitment_failed());
|
||||
}
|
||||
|
|
|
@ -1086,7 +1086,7 @@ struct ConsistencyCheckWorkload : TestWorkload
|
|||
for(auto id : stores.get()) {
|
||||
if(!statefulProcesses[itr->first.address()].count(id)) {
|
||||
TraceEvent("ConsistencyCheck_ExtraDataStore").detail("Address", itr->first.address()).detail("DataStoreID", id);
|
||||
if(g_network->isSimulated()) {
|
||||
if(g_network->isSimulated() && !g_simulator.speedUpSimulation) {
|
||||
g_simulator.rebootProcess(g_simulator.getProcessByAddress(itr->first.address()), ISimulator::RebootProcess);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue