1 /***
2 *
3 * Copyright 2004 Hiram Chirino
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 **/
18 package org.activeio.journal;
19
20 import java.io.File;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.PrintWriter;
24 import java.util.Random;
25
26 import org.activeio.packet.ByteArrayPacket;
27
28 /***
29 * Provides the base class uses to run performance tests against a Journal.
30 * Should be subclassed to customize for specific journal implementation.
31 *
32 * @version $Revision: 1.1 $
33 */
34 abstract public class JournalPerfToolSupport implements JournalEventListener {
35
36 private JournalStatsFilter journal;
37 private Random random = new Random();
38 private byte data[];
39 private int workerCount=0;
40 private PrintWriter statWriter;
41
42
43
44 protected File journalDirectory = new File("journal-logs");
45 protected File statCSVFile = new File("stats.csv");;
46
47
48 protected int workerIncrement=20;
49 protected long incrementDelay=1000*20;
50 protected boolean verbose=true;
51
52
53 protected int recordSize=1024;
54 protected int syncFrequency=15;
55 protected int workerThinkTime=100;
56
57 private final class Worker implements Runnable {
58 public void run() {
59 int i=random.nextInt()%syncFrequency;
60 while(true) {
61 boolean sync=false;
62
63 if( syncFrequency>=0 && (i%syncFrequency)==0 ) {
64 sync=true;
65 }
66 try {
67 journal.write(new ByteArrayPacket(data), sync);
68 Thread.sleep(workerThinkTime);
69 } catch (Exception e) {
70 e.printStackTrace();
71 return;
72 }
73 i++;
74 }
75 }
76 }
77
78 /***
79 * @throws IOException
80 *
81 */
82 protected void exec() throws Exception {
83
84 System.out.println("Client threads write records using: Record Size: "+recordSize+", Sync Frequency: "+syncFrequency+", Worker Think Time: "+workerThinkTime);
85
86
87 data = new byte[recordSize];
88 for (int i = 0; i < data.length; i++) {
89 data[i] = (byte)i;
90 }
91
92 if( statCSVFile!=null ) {
93 statWriter = new PrintWriter(new FileOutputStream(statCSVFile));
94 statWriter.println("Threads,Throughput (k/s),Forcd write latency (ms),Throughput (records/s)");
95 }
96
97 if( journalDirectory.exists() ) {
98 deleteDir(journalDirectory);
99 }
100 journal = new JournalStatsFilter(createJournal()).enableDetailedStats(verbose);
101 journal.setJournalEventListener(this);
102
103 try {
104
105
106
107 while(true) {
108 System.out.println("Starting "+workerIncrement+" Workers...");
109 for(int i=0;i <workerIncrement;i++) {
110 new Thread(new Worker()).start();
111 workerCount++;
112 }
113
114
115 System.out.println("Waiting "+(incrementDelay/1000)+" seconds before next Stat sample.");
116 Thread.sleep(incrementDelay);
117 displayStats();
118 journal.reset();
119 }
120
121
122 } finally {
123 journal.close();
124 }
125 }
126
127 private void displayStats() {
128 System.out.println("Stats at "+workerCount+" workers.");
129 System.out.println(journal);
130 if( statWriter!= null ) {
131 statWriter.println(""+workerCount+","+journal.getThroughputKps()+","+journal.getAvgSyncedLatencyMs()+","+journal.getThroughputRps());
132 statWriter.flush();
133 }
134 }
135
136 /***
137 * @return
138 */
139 abstract public Journal createJournal() throws Exception;
140
141 static private void deleteDir(File f) {
142 File[] files = f.listFiles();
143 for (int i = 0; i < files.length; i++) {
144 File file = files[i];
145 file.delete();
146 }
147 f.delete();
148 }
149
150
151 public void overflowNotification(RecordLocation safeLocation) {
152 try {
153 System.out.println("Mark set: "+safeLocation);
154 journal.setMark(safeLocation, false);
155 } catch (InvalidRecordLocationException e) {
156 e.printStackTrace();
157 } catch (IOException e) {
158 e.printStackTrace();
159 }
160 }
161 }