public static Throwable throwable(@NotNull ValueIn valueIn, boolean appendCurrentStack) { Class type = valueIn.typePrefix(); String preMessage = null; Throwable throwable = ObjectUtils.newInstance((Class<Throwable>) type); final String finalPreMessage = preMessage; final Throwable finalThrowable = throwable; final List<StackTraceElement> stes = new ArrayList<>(); valueIn.marshallable( m -> { final String message = merge(finalPreMessage, m.read(() -> "message").text()); if (message != null) { try { DETAILED_MESSAGE.set(finalThrowable, message); } catch (IllegalAccessException e) { throw Jvm.rethrow(e); } } m.read(() -> "stackTrace") .sequence( stes, (stes0, stackTrace) -> { while (stackTrace.hasNextSequenceItem()) { stackTrace.marshallable( r -> { final String declaringClass = r.read(() -> "class").text(); final String methodName = r.read(() -> "method").text(); final String fileName = r.read(() -> "file").text(); final int lineNumber = r.read(() -> "line").int32(); stes0.add( new StackTraceElement( declaringClass, methodName, fileName, lineNumber)); }); } }); }); if (appendCurrentStack) { stes.add(new StackTraceElement("~ remote", "tcp ~", "", 0)); StackTraceElement[] stes2 = Thread.currentThread().getStackTrace(); int first = 6; int last = Jvm.trimLast(first, stes2); //noinspection ManualArrayToCollectionCopy for (int i = first; i <= last; i++) stes.add(stes2[i]); } try { //noinspection ToArrayCallWithZeroLengthArrayArgument STACK_TRACE.set(finalThrowable, stes.toArray(NO_STE)); } catch (IllegalAccessException e) { throw Jvm.rethrow(e); } return throwable; }
@Test public void testWriteWhileReading() { ClassAliasPool.CLASS_ALIASES.addAlias(Message1.class); ClassAliasPool.CLASS_ALIASES.addAlias(Message2.class); File path1 = Utils.tempDir("testWriteWhileReading1"); File path2 = Utils.tempDir("testWriteWhileReading2"); try (SingleChronicleQueue queue1 = SingleChronicleQueueBuilder.binary(path1).testBlockSize().build(); SingleChronicleQueue queue2 = SingleChronicleQueueBuilder.binary(path2).testBlockSize().build()) { MethodReader reader2 = queue1.createTailer().methodReader(ObjectUtils.printAll(MessageListener.class)); MessageListener writer2 = queue2.acquireAppender().methodWriter(MessageListener.class); MessageListener processor = new MessageProcessor(writer2); MethodReader reader1 = queue1.createTailer().methodReader(processor); MessageListener writer1 = queue1.acquireAppender().methodWriter(MessageListener.class); for (int i = 0; i < 3; i++) { // write a message writer1.method1(new Message1("hello")); writer1.method2(new Message2(234)); // read those messages assertTrue(reader1.readOne()); assertTrue(reader1.readOne()); assertFalse(reader1.readOne()); // read the produced messages assertTrue(reader2.readOne()); assertTrue(reader2.readOne()); assertFalse(reader2.readOne()); } // System.out.println(queue1.dump()); } }