accumulo-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From e..@apache.org
Subject [3/5] accumulo git commit: ACCUMULO-1177 respond to review
Date Wed, 26 Nov 2014 18:28:20 GMT
ACCUMULO-1177 respond to review


Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo
Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/bac65c7f
Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/bac65c7f
Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/bac65c7f

Branch: refs/heads/master
Commit: bac65c7fddf23c2e262fc403ea0d02bb9b41d8a1
Parents: 64433a4
Author: Eric C. Newton <eric.newton@gmail.com>
Authored: Fri Nov 14 16:41:08 2014 -0500
Committer: Eric C. Newton <eric.newton@gmail.com>
Committed: Fri Nov 14 16:41:08 2014 -0500

----------------------------------------------------------------------
 .../org/apache/accumulo/core/conf/Property.java |   2 +-
 .../apache/accumulo/tserver/TabletServer.java   | 105 ++++++++++--------
 .../tserver/TabletServerResourceManager.java    |   3 +-
 .../apache/accumulo/tserver/tablet/Tablet.java  |   1 +
 .../accumulo/test/AssignmentThreadsIT.java      |  35 +++---
 .../accumulo/test/VerifySerialRecoveryIT.java   | 108 +++++++++++++++++++
 .../accumulo/test/functional/BulkFileIT.java    |   2 -
 .../test/functional/FunctionalTestUtils.java    |   2 +-
 8 files changed, 191 insertions(+), 67 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/accumulo/blob/bac65c7f/core/src/main/java/org/apache/accumulo/core/conf/Property.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/accumulo/core/conf/Property.java b/core/src/main/java/org/apache/accumulo/core/conf/Property.java
index 5044c09..c2c3587 100644
--- a/core/src/main/java/org/apache/accumulo/core/conf/Property.java
+++ b/core/src/main/java/org/apache/accumulo/core/conf/Property.java
@@ -295,7 +295,7 @@ public enum Property {
   TSERV_REPLICATION_DEFAULT_HANDLER("tserver.replication.default.replayer", "org.apache.accumulo.tserver.replication.BatchWriterReplicationReplayer",
       PropertyType.CLASSNAME, "Default AccumuloReplicationReplayer implementation"),
   TSERV_REPLICATION_BW_REPLAYER_MEMORY("tserver.replication.batchwriter.replayer.memory",
"50M", PropertyType.MEMORY, "Memory to provide to batchwriter to replay mutations for replication"),
-  TSERV_ASSIGNMENT_MAXCONCURRENT("tserver.assignement.concurrent.max", "2", PropertyType.COUNT,
"The number of threads available to load tablets."),
+  TSERV_ASSIGNMENT_MAXCONCURRENT("tserver.assignment.concurrent.max", "2", PropertyType.COUNT,
"The number of threads available to load tablets. Recoveries are still performed serially."),
 
   // properties that are specific to logger server behavior
   LOGGER_PREFIX("logger.", null, PropertyType.PREFIX, "Properties in this category affect
the behavior of the write-ahead logger servers"),

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bac65c7f/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
index 55785a3..5574384 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServer.java
@@ -16,9 +16,6 @@
  */
 package org.apache.accumulo.tserver;
 
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static org.apache.accumulo.server.problems.ProblemType.TABLET_LOAD;
-
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.lang.management.ManagementFactory;
@@ -54,6 +51,7 @@ import java.util.concurrent.atomic.AtomicLong;
 
 import javax.management.StandardMBean;
 
+import com.google.common.net.HostAndPort;
 import org.apache.accumulo.core.Constants;
 import org.apache.accumulo.core.client.AccumuloException;
 import org.apache.accumulo.core.client.AccumuloSecurityException;
@@ -239,7 +237,8 @@ import org.apache.thrift.TServiceClient;
 import org.apache.thrift.server.TServer;
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.KeeperException.NoNodeException;
-import com.google.common.net.HostAndPort;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.accumulo.server.problems.ProblemType.TABLET_LOAD;
 
 public class TabletServer implements Runnable {
   private static final Logger log = Logger.getLogger(TabletServer.class);
@@ -358,7 +357,7 @@ public class TabletServer implements Runnable {
 
   private final AtomicLong totalQueuedMutationSize = new AtomicLong(0);
   private final Semaphore recoverySemaphore = new Semaphore(1, true);
-
+  
   private class ThriftClientHandler extends ClientServiceHandler implements TabletClientService.Iface
{
 
     ThriftClientHandler() {
@@ -2126,21 +2125,25 @@ public class TabletServer implements Runnable {
         // this opens the tablet file and fills in the endKey in the
         // extent
         locationToOpen = VolumeUtil.switchRootTabletVolume(extent, locationToOpen);
-        tablet = new Tablet(TabletServer.this, extent, locationToOpen, trm, tabletsKeyValues);
-        /*
-         * If a minor compaction starts after a tablet opens, this indicates a log recovery
occurred. This recovered data must be minor compacted.
-         *
-         * There are three reasons to wait for this minor compaction to finish before placing
the tablet in online tablets.
-         *
-         * 1) The log recovery code does not handle data written to the tablet on multiple
tablet servers. 2) The log recovery code does not block if memory is
-         * full. Therefore recovering lots of tablets that use a lot of memory could run
out of memory. 3) The minor compaction finish event did not make it to
-         * the logs (the file will be in metadata, preventing replay of compacted data)...
but do not want a majc to wipe the file out from metadata and then
-         * have another process failure... this could cause duplicate data to replay
-         */
-        if (tablet.getNumEntriesInMemory() > 0 && !tablet.minorCompactNow(MinorCompactionReason.RECOVERY))
{
-          throw new RuntimeException("Minor compaction after recovery fails for " + extent);
-        }
 
+        acquireRecoveryMemory(extent);
+        {
+
+          tablet = new Tablet(TabletServer.this, extent, locationToOpen, trm, tabletsKeyValues);
+          /*
+           * If a minor compaction starts after a tablet opens, this indicates a log recovery
occurred. This recovered data must be minor compacted.
+           *
+           * There are three reasons to wait for this minor compaction to finish before placing
the tablet in online tablets.
+           *
+           * 1) The log recovery code does not handle data written to the tablet on multiple
tablet servers. 2) The log recovery code does not block if memory is
+           * full. Therefore recovering lots of tablets that use a lot of memory could run
out of memory. 3) The minor compaction finish event did not make it to
+           * the logs (the file will be in metadata, preventing replay of compacted data)...
but do not want a majc to wipe the file out from metadata and then
+           * have another process failure... this could cause duplicate data to replay
+           */
+          if (tablet.getNumEntriesInMemory() > 0 && !tablet.minorCompactNow(MinorCompactionReason.RECOVERY))
{
+            throw new RuntimeException("Minor compaction after recovery fails for " + extent);
+          }
+        }
         Assignment assignment = new Assignment(extent, getTabletSession());
         TabletStateStore.setLocation(assignment);
 
@@ -2160,6 +2163,8 @@ public class TabletServer implements Runnable {
           log.warn(e.getMessage());
         String table = extent.getTableId().toString();
         ProblemReports.getInstance().report(new ProblemReport(table, TABLET_LOAD, extent.getUUID().toString(),
getClientAddressString(), e));
+      } finally {
+        releaseRecoveryMemory(extent);
       }
 
       if (!successful) {
@@ -2196,6 +2201,18 @@ public class TabletServer implements Runnable {
     }
   }
 
+  private void acquireRecoveryMemory(KeyExtent extent) throws InterruptedException {
+    if (!extent.isMeta()) {
+      recoverySemaphore.acquireUninterruptibly();
+    }
+  }
+
+  private void releaseRecoveryMemory(KeyExtent extent) {
+    if (!extent.isMeta()) {
+      recoverySemaphore.release();
+    }
+  }
+  
   public void addLoggersToMetadata(List<DfsLogger> logs, KeyExtent extent, int id)
{
     if (!this.onlineTablets.containsKey(extent)) {
       log.info("Not adding " + logs.size() + " logs for extent " + extent + " as alias "
+ id + " tablet is offline");
@@ -2906,37 +2923,31 @@ public class TabletServer implements Runnable {
   }
 
   public void recover(VolumeManager fs, KeyExtent extent, TableConfiguration tconf, List<LogEntry>
logEntries, Set<String> tabletFiles, MutationReceiver mutationReceiver)
-      throws IOException, InterruptedException {
-    recoverySemaphore.acquire();
-    try {
-      log.info("Starting Write-Ahead Log recovery for " + extent);
-      List<Path> recoveryLogs = new ArrayList<Path>();
-      List<LogEntry> sorted = new ArrayList<LogEntry>(logEntries);
-      Collections.sort(sorted, new Comparator<LogEntry>() {
-        @Override
-        public int compare(LogEntry e1, LogEntry e2) {
-          return (int) (e1.timestamp - e2.timestamp);
-        }
-      });
-      for (LogEntry entry : sorted) {
-        Path recovery = null;
-        for (String log : entry.logSet) {
-          Path finished = RecoveryPath.getRecoveryPath(fs, fs.getFullPath(FileType.WAL, log));
-          finished = SortedLogState.getFinishedMarkerPath(finished);
-          TabletServer.log.info("Looking for " + finished);
-          if (fs.exists(finished)) {
-            recovery = finished.getParent();
-            break;
-          }
+      throws IOException {
+    List<Path> recoveryLogs = new ArrayList<Path>();
+    List<LogEntry> sorted = new ArrayList<LogEntry>(logEntries);
+    Collections.sort(sorted, new Comparator<LogEntry>() {
+      @Override
+      public int compare(LogEntry e1, LogEntry e2) {
+        return (int) (e1.timestamp - e2.timestamp);
+      }
+    });
+    for (LogEntry entry : sorted) {
+      Path recovery = null;
+      for (String log : entry.logSet) {
+        Path finished = RecoveryPath.getRecoveryPath(fs, fs.getFullPath(FileType.WAL, log));
+        finished = SortedLogState.getFinishedMarkerPath(finished);
+        TabletServer.log.info("Looking for " + finished);
+        if (fs.exists(finished)) {
+          recovery = finished.getParent();
+          break;
         }
-        if (recovery == null)
-          throw new IOException("Unable to find recovery files for extent " + extent + "
logEntry: " + entry);
-        recoveryLogs.add(recovery);
       }
-      logger.recover(fs, extent, tconf, recoveryLogs, tabletFiles, mutationReceiver);
-    } finally {
-      recoverySemaphore.release();
+      if (recovery == null)
+        throw new IOException("Unable to find recovery files for extent " + extent + " logEntry:
" + entry);
+      recoveryLogs.add(recovery);
     }
+    logger.recover(fs, extent, tconf, recoveryLogs, tabletFiles, mutationReceiver);
   }
 
   public int createLogId(KeyExtent tablet) {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bac65c7f/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServerResourceManager.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServerResourceManager.java
b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServerResourceManager.java
index 6ac6354..90e5802 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServerResourceManager.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/TabletServerResourceManager.java
@@ -198,8 +198,7 @@ public class TabletServerResourceManager {
     // concurrent assignments would put more load on the metadata table at startup
     assignmentPool = createEs(Property.TSERV_ASSIGNMENT_MAXCONCURRENT, "tablet assignment");
 
-    int max = acuConf.getCount(Property.TSERV_ASSIGNMENT_MAXCONCURRENT);
-    assignMetaDataPool = createEs(0, max, 60, "metadata tablet assignment");
+    assignMetaDataPool = createEs(0, 1, 60, "metadata tablet assignment");
 
     activeAssignments = new ConcurrentHashMap<KeyExtent,RunnableStartedAt>();
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bac65c7f/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java
----------------------------------------------------------------------
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java
index 6e4b459..9490903 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/tablet/Tablet.java
@@ -585,6 +585,7 @@ public class Tablet implements TabletCommitter {
     configObserver.propertiesChanged();
 
     if (!logEntries.isEmpty()) {
+      log.info("Starting Write-Ahead Log recovery for " + this.extent);
       // count[0] = entries used on tablet
       // count[1] = track max time from walog entries wihtout timestamps
       final long[] count = new long[2];

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bac65c7f/test/src/test/java/org/apache/accumulo/test/AssignmentThreadsIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/AssignmentThreadsIT.java b/test/src/test/java/org/apache/accumulo/test/AssignmentThreadsIT.java
index 01d53a3..d7a5ac2 100644
--- a/test/src/test/java/org/apache/accumulo/test/AssignmentThreadsIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/AssignmentThreadsIT.java
@@ -31,6 +31,7 @@ import org.junit.Test;
 
 import static org.junit.Assert.assertTrue;
 
+// ACCUMULO-1177
 public class AssignmentThreadsIT extends ConfigurableMacIT {
 
   @Override
@@ -38,26 +39,32 @@ public class AssignmentThreadsIT extends ConfigurableMacIT {
     cfg.setNumTservers(1);
     cfg.setProperty(Property.TSERV_ASSIGNMENT_MAXCONCURRENT, "1");
   }
-  
+
+  // [0-9a-f]
+  private final static byte[] HEXCHARS = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66 };
+  private final static Random random = new Random();
+
+  public static byte[] randomHex(int n) {
+    byte[] binary = new byte[n];
+    byte[] hex = new byte[n * 2];
+    random.nextBytes(binary);
+    int count = 0;
+    for (byte x : binary) {
+      hex[count++] = HEXCHARS[(x >> 4)&0xf];
+      hex[count++] = HEXCHARS[x&0xf];
+    }
+    return hex;
+  }
+
   @Test(timeout = 5 * 60 * 1000)
-  public void test() throws Exception {
-    byte[] HEXCHARS = { 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61,
0x62, 0x63, 0x64, 0x65, 0x66 };
+  public void testConcurrentAssignmentPerformance() throws Exception {
     // make a table with a lot of splits
     String tableName = getUniqueNames(1)[0];
     Connector c = getConnector();
     c.tableOperations().create(tableName);
     SortedSet<Text> splits = new TreeSet<Text>();
-    Random random = new Random();
-    byte[] split = new byte[8];
-    byte[] hex = new byte[split.length * 2];
     for (int i = 0; i < 4000; i++) {
-      random.nextBytes(split);
-      int count = 0;
-      for (byte x : split) {
-        hex[count++] = HEXCHARS[(x >> 4)&0xf];
-        hex[count++] = HEXCHARS[x&0xf];
-      }
-      splits.add(new Text(hex));
+      splits.add(new Text(randomHex(8)));
     }
     c.tableOperations().addSplits(tableName, splits);
     c.tableOperations().offline(tableName, true);
@@ -77,5 +84,5 @@ public class AssignmentThreadsIT extends ConfigurableMacIT {
     log.debug("Loaded " + splits.size() + " tablets in " + diff2 + " ms");
     assertTrue(diff2 < diff);
   }
-  
+
 }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bac65c7f/test/src/test/java/org/apache/accumulo/test/VerifySerialRecoveryIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/VerifySerialRecoveryIT.java b/test/src/test/java/org/apache/accumulo/test/VerifySerialRecoveryIT.java
new file mode 100644
index 0000000..525a29a
--- /dev/null
+++ b/test/src/test/java/org/apache/accumulo/test/VerifySerialRecoveryIT.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ package org.apache.accumulo.test;
+
+import java.util.Map.Entry;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.accumulo.core.client.BatchWriter;
+import org.apache.accumulo.core.client.Connector;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.data.Key;
+import org.apache.accumulo.core.data.Mutation;
+import org.apache.accumulo.core.data.Value;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.minicluster.ServerType;
+import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
+import org.apache.accumulo.minicluster.impl.ProcessReference;
+import org.apache.accumulo.server.util.Admin;
+import org.apache.accumulo.test.functional.ConfigurableMacIT;
+import org.apache.accumulo.test.functional.FunctionalTestUtils;
+import org.apache.accumulo.tserver.TabletServer;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.RawLocalFileSystem;
+import org.apache.hadoop.io.Text;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class VerifySerialRecoveryIT extends ConfigurableMacIT {
+  
+  @Override
+  public void configure(MiniAccumuloConfigImpl cfg, Configuration hadoopCoreSite) {
+    cfg.setNumTservers(1);
+    cfg.setProperty(Property.TSERV_ASSIGNMENT_MAXCONCURRENT, "20");
+    hadoopCoreSite.set("fs.file.impl", RawLocalFileSystem.class.getName());
+  }
+  
+  @Test(timeout = 4 * 60 * 1000)
+  public void testSerializedRecovery() throws Exception {
+    // make a table with many splits
+    String tableName = getUniqueNames(1)[0];
+    Connector c = getConnector();
+    c.tableOperations().create(tableName);
+    SortedSet<Text> splits = new TreeSet<Text>();
+    for (int i = 0; i < 200; i++) {
+      splits.add(new Text(AssignmentThreadsIT.randomHex(8)));
+    }
+    c.tableOperations().addSplits(tableName, splits);
+    // load data to give the recovery something to do
+    BatchWriter bw = c.createBatchWriter(tableName, null);
+    for (int i = 0; i < 50000; i++) {
+      Mutation m = new Mutation(AssignmentThreadsIT.randomHex(8));
+      m.put("", "", "");
+      bw.addMutation(m);
+    }
+    bw.close();
+    // kill the tserver
+    for (ProcessReference ref : getCluster().getProcesses().get(ServerType.TABLET_SERVER))
+      getCluster().killProcess(ServerType.TABLET_SERVER, ref);
+    final Process ts = cluster.exec(TabletServer.class);
+    
+    // wait for recovery
+    for (@SuppressWarnings("unused") Entry<Key,Value> entry : c.createScanner(tableName,
Authorizations.EMPTY))
+      ;
+    assertEquals(0, cluster.exec(Admin.class, "stopAll").waitFor());
+    ts.waitFor();
+    String result = FunctionalTestUtils.readAll(cluster, TabletServer.class, ts);
+    for (String line : result.split("\n")) {
+      System.out.println(line);
+    }
+    // walk through the output, verifying that only a single normal recovery was running
at one time
+    boolean started = false;
+    int recoveries = 0;
+    for (String line : result.split("\n")) {
+      // ignore metadata tables
+      if (line.contains("!0") || line.contains("+r"))
+        continue;
+      if (line.contains("Starting Write-Ahead Log")) {
+        assertFalse(started);
+        started = true;
+        recoveries++;
+      }
+      if (line.contains("Write-Ahead Log recovery complete")) {
+        assertTrue(started);
+        started = false;
+      }
+    }
+    assertFalse(started);
+    assertTrue(recoveries > 0);
+  }  
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bac65c7f/test/src/test/java/org/apache/accumulo/test/functional/BulkFileIT.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/BulkFileIT.java b/test/src/test/java/org/apache/accumulo/test/functional/BulkFileIT.java
index 475d5cf..556df01 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/BulkFileIT.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/BulkFileIT.java
@@ -37,8 +37,6 @@ import org.apache.accumulo.core.volume.VolumeConfiguration;
 import org.apache.accumulo.minicluster.MemoryUnit;
 import org.apache.accumulo.minicluster.ServerType;
 import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl;
-import org.apache.accumulo.server.conf.ServerConfiguration;
-import org.apache.accumulo.server.trace.TraceFileSystem;
 import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.fs.Path;

http://git-wip-us.apache.org/repos/asf/accumulo/blob/bac65c7f/test/src/test/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java
----------------------------------------------------------------------
diff --git a/test/src/test/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java
b/test/src/test/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java
index 1246efe..4e0721b 100644
--- a/test/src/test/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java
+++ b/test/src/test/java/org/apache/accumulo/test/functional/FunctionalTestUtils.java
@@ -148,7 +148,7 @@ public class FunctionalTestUtils {
     return result.toString();
   }
 
-  static String readAll(MiniAccumuloClusterImpl c, Class<?> klass, Process p) throws
Exception {
+  public static String readAll(MiniAccumuloClusterImpl c, Class<?> klass, Process p)
throws Exception {
     for (LogWriter writer : c.getLogWriters())
       writer.flush();
     return readAll(new FileInputStream(c.getConfig().getLogDir() + "/" + klass.getSimpleName()
+ "_" + p.hashCode() + ".out"));


Mime
View raw message