/** * pretouch() has to be run on the same thread, as the thread that created the appender. * If you want to use pretouch() in another thread, you must first create or have an appender that * was created on this thread, and then use this appender to call the pretouch() */ @Override public void pretouch() { if (queue.isClosed()) throw new RuntimeException("Queue Closed"); try { if (pretoucher == null) pretoucher = new Pretoucher(queue()); pretoucher.execute(); } catch (Throwable e) { Jvm.warn().on(getClass(), e); Jvm.rethrow(e); } }
@Override public void writeEOF(@NotNull Wire wire, long timeoutMS) { // just in case we are about to release this if (wire.bytes().tryReserve()) { wire.writeEndOfWire(timeoutMS, TimeUnit.MILLISECONDS, writePosition()); wire.bytes().release(); } else { Jvm.debug().on(getClass(), "Tried to writeEOF to as it was being closed"); } }
public StoreFileListener storeFileListener() { return storeFileListener == null ? (cycle, file) -> { if (Jvm.isDebugEnabled(getClass())) Jvm.debug().on(getClass(), "File released " + file); } : storeFileListener; }
@Override public synchronized void release(@NotNull CommonStore store) { store.release(); long refCount = store.refCount(); assert refCount >= 0; if (refCount == 0) { for (Map.Entry<RollDetails, WeakReference<WireStore>> entry : stores.entrySet()) { WeakReference<WireStore> ref = entry.getValue(); if (ref != null && ref.get() == store) { stores.remove(entry.getKey()); storeFileListener.onReleased(entry.getKey().cycle(), store.file()); return; } } if (Jvm.isDebugEnabled(getClass())) Jvm.debug().on(getClass(), "Store was not registered: " + store.file()); } }
boolean checkWritePositionHeaderNumber() { if (wire == null || wire.headerNumber() == Long.MIN_VALUE) return true; try { long pos = position; long seq1 = queue.rollCycle().toSequenceNumber(wire.headerNumber() + 1) - 1; long seq2 = store.sequenceForPosition(this, pos, true); if (seq1 != seq2) { // System.out.println(queue.dump()); String message = "~~~~~~~~~~~~~~ " + "thread: " + Thread.currentThread().getName() + " pos: " + pos + " header: " + wire.headerNumber() + " seq1: " + seq1 + " seq2: " + seq2; //System.err.println(message); new AssertionError(message).printStackTrace(); throw new AssertionError(message); } } catch (Exception e) { Jvm.fatal().on(getClass(), e); throw Jvm.rethrow(e); } return true; }
public static long hash64(@NotNull String s) { long hash = 0; if (Jvm.isJava9Plus()) { final byte[] bytes = StringUtils.extractBytes(s); for (int i = 0, len = s.length(); i < len; i++) hash = hash * 841248317 + bytes[i]; } else { final char[] chars = StringUtils.extractChars(s); for (int i = 0, len = s.length(); i < len; i++) hash = hash * 841248317 + chars[i]; } return agitate(hash); }
private static void deleteFiles(@NotNull File element) throws IOException { if (element.isDirectory()) { @Nullable File[] files = element.listFiles(); if (files == null) return; for (@NotNull File sub : files) { deleteFiles(sub); } } try { Files.deleteIfExists(element.toPath()); } catch (IOException e) { Jvm.debug().on(ChronicleQueueView.class, "Unable to delete " + element, e); } }
@NotNull private static Memory getMemory() { @Nullable Memory memory = null; try { Class<? extends Memory> java9MemoryClass = Class .forName("software.chronicle.enterprise.core.Java9Memory") .asSubclass(Memory.class); Method create = java9MemoryClass.getMethod("create"); memory = (Memory) create.invoke(null); } catch (ClassNotFoundException expected) { // expected } catch (@NotNull NoSuchMethodException | InvocationTargetException | IllegalAccessException | IllegalArgumentException e) { Jvm.warn().on(OS.class, "Unable to load Java9MemoryClass", e); } if (memory == null) memory = UnsafeMemory.INSTANCE; return memory; }
public void assertNoNewThreads() { @Nullable Map<Thread, StackTraceElement[]> allStackTraces = null; for (int i = 1; i < 5; i++) { Jvm.pause(i * i * 50); allStackTraces = Thread.getAllStackTraces(); allStackTraces.keySet().removeAll(threads); if (allStackTraces.isEmpty()) return; allStackTraces.keySet().removeIf(next -> ignored.stream().anyMatch(item -> next.getName().contains(item))); if (allStackTraces.isEmpty()) return; for (@NotNull Map.Entry<Thread, StackTraceElement[]> threadEntry : allStackTraces.entrySet()) { @NotNull StringBuilder sb = new StringBuilder(); sb.append("Thread still running ").append(threadEntry.getKey()); Jvm.trimStackTrace(sb, threadEntry.getValue()); System.err.println(sb); } } throw new AssertionError("Threads still running " + allStackTraces.keySet()); } }
/** * Log the stack trace of the thread holding a lock. * * @param lock to log * @return the lock.toString plus a stack trace. */ public static String lockWithStack(@NotNull ReentrantLock lock) { @Nullable Thread t = getValue(lock, "sync/exclusiveOwnerThread"); if (t == null) { return lock.toString(); } @NotNull StringBuilder ret = new StringBuilder(); ret.append(lock).append(" running at"); trimStackTrace(ret, t.getStackTrace()); return ret.toString(); }
private long writeHeader(@NotNull Wire wire, int safeLength) { Bytes<?> bytes = wire.bytes(); // writePosition points at the last record in the queue, so we can just skip it and we're ready for write long pos = position; long lastPos = store.writePosition(); if (pos < lastPos) { // queue moved since we last touched it - recalculate header number try { wire.headerNumber(queue.rollCycle().toIndex(cycle, store.lastSequenceNumber(this))); } catch (StreamCorruptedException ex) { Jvm.warn().on(getClass(), "Couldn't find last sequence", ex); } } int header = bytes.readVolatileInt(lastPos); assert header != NOT_INITIALIZED; lastPos += lengthOf(bytes.readVolatileInt(lastPos)) + SPB_HEADER_SIZE; bytes.writePosition(lastPos); return wire.enterHeader(safeLength); }
@Override public long recoverAndWriteHeader(@NotNull Wire wire, long timeoutMS, @NotNull final LongValue lastPosition, Sequence sequence) throws UnrecoverableTimeoutException { Jvm.warn().on(getClass(), "Clearing an incomplete header so a header can be written"); wire.bytes().writeInt(0); wire.pauser().reset(); try { return wire.writeHeaderOfUnknownLength(timeoutMS, TimeUnit.MILLISECONDS, lastPosition, sequence); } catch (@NotNull TimeoutException | EOFException e) { throw new UnrecoverableTimeoutException(e); } } }
public static void dumpException(@NotNull Map<ExceptionKey, Integer> exceptions) { System.out.println("exceptions: " + exceptions.size()); for (@NotNull Map.Entry<ExceptionKey, Integer> entry : exceptions.entrySet()) { ExceptionKey key = entry.getKey(); System.err.println(key.level + " " + key.clazz.getSimpleName() + " " + key.message); if (key.throwable != null) key.throwable.printStackTrace(); Integer value = entry.getValue(); if (value > 1) System.err.println("Repeated " + value + " times"); } resetExceptionHandlers(); }
@NotNull @Override public DocumentContext readingDocument(boolean includeMetaData) { Jvm.optionalSafepoint(); Jvm.optionalSafepoint(); boolean next = false, tryAgain = true; if (state == FOUND_CYCLE) { try { Jvm.optionalSafepoint(); next = inACycle(includeMetaData); Jvm.optionalSafepoint(); Jvm.optionalSafepoint(); Jvm.optionalSafepoint(); if (context.present(next)) { Bytes<?> bytes = context.wire().bytes(); context.setStart(bytes.readPosition() - 4); readingDocumentFound = true; address = bytes.addressForRead(bytes.readPosition(), 4); Jvm.optionalSafepoint(); return context; Jvm.optionalSafepoint(); Jvm.warn().on(StoreTailer.class, "Tried to read past the end of a read-only view. " + "Underlying data store may have grown since this tailer was created.", e); } else {
public void writeBytes(long index, @NotNull BytesStore bytes) { rollCycleTo(cycle); boolean rollbackDontClose = index != wire.headerNumber() + 1; if (rollbackDontClose) { if (index > wire.headerNumber() + 1) throw new IllegalStateException("Unable to move to index " + Long.toHexString(index) + " beyond the end of the queue"); Jvm.warn().on(getClass(), "Trying to overwrite index " + Long.toHexString(index) + " which is before the end of the queue"); return;