use of org.qi4j.io.Output in project qi4j-sdk by Qi4j.
the class GaeEntityStoreMixin method entityStates.
@Override
public Input<Reader, IOException> entityStates() {
return new Input<Reader, IOException>() {
@Override
public <ReceiverThrowableType extends Throwable> void transferTo(Output<? super Reader, ReceiverThrowableType> output) throws IOException, ReceiverThrowableType {
Query query = new Query();
PreparedQuery preparedQuery = datastore.prepare(query);
final QueryResultIterable<Entity> iterable = preparedQuery.asQueryResultIterable();
output.receiveFrom(new Sender<Reader, IOException>() {
@Override
public <ReceiverThrowableType extends Throwable> void sendTo(Receiver<? super Reader, ReceiverThrowableType> receiver) throws ReceiverThrowableType, IOException {
for (Entity entity : iterable) {
Text serializedState = (Text) entity.getProperty("value");
receiver.receive(new StringReader(serializedState.getValue()));
}
}
});
}
};
}
use of org.qi4j.io.Output in project qi4j-sdk by Qi4j.
the class JdbmEntityStoreMixin method restore.
@Override
public Output<String, IOException> restore() {
return new Output<String, IOException>() {
@Override
public <SenderThrowableType extends Throwable> void receiveFrom(Sender<? extends String, SenderThrowableType> sender) throws IOException, SenderThrowableType {
File dbFile = new File(getDatabaseName() + ".db");
File lgFile = new File(getDatabaseName() + ".lg");
// Create temporary store
File tempDatabase = Files.createTemporayFileOf(dbFile);
final RecordManager recordManager = RecordManagerFactory.createRecordManager(tempDatabase.getAbsolutePath(), new Properties());
ByteArrayComparator comparator = new ByteArrayComparator();
final BTree index = BTree.createInstance(recordManager, comparator, serializer, DefaultSerializer.INSTANCE, 16);
recordManager.setNamedObject("index", index.getRecid());
recordManager.commit();
try {
sender.sendTo(new Receiver<String, IOException>() {
int counter = 0;
@Override
public void receive(String item) throws IOException {
// Commit one batch
if ((counter++ % 1000) == 0) {
recordManager.commit();
}
String id = item.substring("{\"identity\":\"".length());
id = id.substring(0, id.indexOf('"'));
// Insert
byte[] stateArray = item.getBytes("UTF-8");
long stateIndex = recordManager.insert(stateArray, serializer);
index.insert(id.getBytes("UTF-8"), stateIndex, false);
}
});
} catch (IOException e) {
recordManager.close();
tempDatabase.delete();
throw e;
} catch (Throwable senderThrowableType) {
recordManager.close();
tempDatabase.delete();
throw (SenderThrowableType) senderThrowableType;
}
// Import went ok - continue
recordManager.commit();
// close file handles otherwise Microsoft Windows will fail to rename database files.
recordManager.close();
lock.writeLock().lock();
try {
// Replace old database with new
JdbmEntityStoreMixin.this.recordManager.close();
boolean deletedOldDatabase = true;
deletedOldDatabase &= dbFile.delete();
deletedOldDatabase &= lgFile.delete();
if (!deletedOldDatabase) {
throw new IOException("Could not remove old database");
}
boolean renamedTempDatabase = true;
renamedTempDatabase &= new File(tempDatabase.getAbsolutePath() + ".db").renameTo(dbFile);
renamedTempDatabase &= new File(tempDatabase.getAbsolutePath() + ".lg").renameTo(lgFile);
if (!renamedTempDatabase) {
throw new IOException("Could not replace database with temp database");
}
// Start up again
initialize();
} finally {
lock.writeLock().unlock();
}
}
};
}
use of org.qi4j.io.Output in project qi4j-sdk by Qi4j.
the class AbstractApplicationEventStoreMixin method storeEvents.
// This is how transactions are put into the store
@Override
public TransactionApplicationEvents storeEvents(Iterable<ApplicationEvent> events) throws IOException {
// Create new TransactionApplicationEvents
ValueBuilder<TransactionApplicationEvents> builder = vbf.newValueBuilder(TransactionApplicationEvents.class);
Iterables.addAll(builder.prototype().events().get(), events);
builder.prototype().timestamp().set(getCurrentTimestamp());
final TransactionApplicationEvents transactionDomain = builder.newInstance();
// Lock store so noone else can interrupt
lock();
try {
storeEvents(transactionDomain);
} finally {
lock.unlock();
}
// Notify listeners
transactionNotifier.submit(new Runnable() {
@Override
public void run() {
synchronized (listeners) {
Input<TransactionApplicationEvents, RuntimeException> input = Inputs.iterable(Collections.singleton(transactionDomain));
for (Output<TransactionApplicationEvents, ? extends Throwable> listener : listeners) {
try {
input.transferTo(listener);
} catch (Throwable e) {
logger.warn("Could not notify event listener", e);
}
}
}
}
});
return transactionDomain;
}
Aggregations