Skip to content

Commit d22704d

Browse files
committed
added common stats generation
1 parent 89e3d42 commit d22704d

3 files changed

Lines changed: 221 additions & 10 deletions

File tree

src/main/java/de/unirostock/sems/cbarchive/web/Fields.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ public class Fields {
7575

7676
/** Link to the sedML WebTools for starting a simulation */
7777
public static String SEDML_WEBTOOLS_URL = null;
78+
79+
/** max time for caching statistic data */
80+
public static long MAX_STATS_AGE = 180;
7881

7982
// ------------------------------------------------------------------------
8083
// Quotas
@@ -145,6 +148,9 @@ else if (desiredLogLevel.equals ("NONE"))
145148
else
146149
Fields.SEDML_WEBTOOLS_URL = null;
147150

151+
// max stats age
152+
MAX_STATS_AGE = parseLong( context.getInitParameter("MAX_STATS_AGE"), MAX_STATS_AGE );
153+
148154
// Quotas
149155

150156
QUOTA_TOTAL_SIZE = parseQuotaFromString( context.getInitParameter("QUOTA_TOTAL_SIZE") );
@@ -172,15 +178,19 @@ else if (desiredLogLevel.equals ("NONE"))
172178
}
173179

174180
private static long parseQuotaFromString( String string ) {
181+
return parseLong(string, QUOTA_UNLIMITED);
182+
}
183+
184+
private static long parseLong( String string, long defaultValue ) {
175185

176186
if( string == null || string.isEmpty() )
177-
return QUOTA_UNLIMITED;
187+
return defaultValue;
178188

179189
try {
180190
return Long.parseLong(string);
181191
} catch (NumberFormatException e) {
182-
LOGGER.warn("Bad format for quota in the context settings: ", string);
183-
return QUOTA_UNLIMITED;
192+
LOGGER.warn("Bad number format in the context settings: ", string);
193+
return defaultValue;
184194
}
185195
}
186196

src/main/java/de/unirostock/sems/cbarchive/web/QuotaManager.java

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.concurrent.locks.ReentrantLock;
2727

2828
import de.binfalse.bflog.LOGGER;
29+
import de.unirostock.sems.cbarchive.web.dataholder.StatisticData;
2930
import de.unirostock.sems.cbarchive.web.dataholder.Workspace;
3031

3132
public class QuotaManager {
@@ -49,6 +50,12 @@ public static QuotaManager getInstance() {
4950
protected Map<String, Long> workspaceCache = new HashMap<String, Long>();
5051
protected WorkspaceManager workspaceManager = null;
5152
protected long totalSize = 0L;
53+
54+
protected Thread workerThread = null;
55+
protected long workerExecutionTime = 0L;
56+
57+
protected StatisticData stats = null;
58+
protected Date statsTimestamp = null;
5259

5360
private QuotaManager() {
5461

@@ -71,7 +78,10 @@ public long getTotalSize() {
7178
*/
7279
public void forceAsyncScan( boolean storeSettingsAfterwards ) {
7380

74-
new Thread( new Worker(this, storeSettingsAfterwards) ).start();
81+
if( workerThread == null || workerThread.isAlive() == false ) {
82+
workerThread = new Thread( new Worker(this, storeSettingsAfterwards) );
83+
workerThread.start();
84+
}
7585

7686
}
7787

@@ -103,7 +113,33 @@ public long updateWorkspace( String workspaceId ) {
103113
else
104114
return updateWorkspace( workspace );
105115
}
106-
116+
117+
public StatisticData getStats() {
118+
119+
// if cache is ok
120+
if( stats != null && statsTimestamp != null && (new Date().getTime() - statsTimestamp.getTime() + workerExecutionTime)/1000 < Fields.MAX_STATS_AGE )
121+
return stats;
122+
else {
123+
generateStats();
124+
return stats;
125+
}
126+
}
127+
128+
private void generateStats() {
129+
130+
if( (workerThread == null || workerThread.isAlive() == false) && workerLock.tryLock() ) {
131+
workerThread = new Thread( new Worker(this, true) );
132+
workerLock.unlock();
133+
workerThread.start();
134+
}
135+
136+
// wait for the thread to finish
137+
while( workerThread.isAlive() ) {
138+
workerLock.lock();
139+
}
140+
workerLock.unlock();
141+
}
142+
107143
/**
108144
* Updates the size of the workspace
109145
* @param workspace
@@ -170,6 +206,7 @@ public Worker( QuotaManager quotaManager, boolean storeSettingsAfterwards ) {
170206

171207
@Override
172208
public void run() {
209+
long startTime = new Date().getTime();
173210

174211
// runs only once per time
175212
if( quotaManager.workerLock.tryLock() == false )
@@ -178,29 +215,60 @@ public void run() {
178215
LOGGER.info("start full quota scan");
179216

180217
// scan all workspaces
181-
long totalSize = 0;
182-
long size = 0;
218+
long totalSize = 0L;
219+
long totalArchiveCount = 0L;
220+
long totalWorkspaceAge = 0L;
221+
long workspaceCount = 0L;
183222
Map<String, Long> cache = new HashMap<String, Long>();
223+
Date now = new Date();
224+
long nowTime = now.getTime();
184225

185226
// clone collection in order to not get the iterator broken by some manipulations form other threads
186227
List<Workspace> collection = new ArrayList<Workspace>( quotaManager.workspaceManager.workspaces.values() );
187228
for( Workspace workspace : collection ) {
188229

189-
size = quotaManager.scanWorkspace(workspace);
190-
if( size > 0 )
230+
long size = quotaManager.scanWorkspace(workspace);
231+
if( size > 0 ) {
191232
cache.put( workspace.getWorkspaceId(), size );
192-
totalSize += size;
233+
234+
totalSize += size;
235+
totalArchiveCount += workspace.getArchives().size();
236+
totalWorkspaceAge += (nowTime - workspace.getLastseen().getTime())/1000;
237+
workspaceCount++;
238+
}
193239
}
194240

241+
// generate stats
242+
StatisticData stats = new StatisticData();
243+
stats.setGenerated(now);
244+
245+
stats.setTotalSize(totalSize);
246+
stats.setWorkspaceCount(workspaceCount);
247+
stats.setSizePerWorkspace( (double) totalSize / (double) workspaceCount );
248+
stats.setArchivesPerWorkspace( (double) totalArchiveCount / (double) workspaceCount );
249+
stats.setAvgWorkspaceAge( (double) totalWorkspaceAge / (double) workspaceCount );
250+
251+
if( Fields.QUOTA_WORKSPACE_SIZE != Fields.QUOTA_UNLIMITED )
252+
stats.setAvgWorkspaceSizeQuota( (double) Fields.QUOTA_WORKSPACE_SIZE / stats.getSizePerWorkspace() );
253+
if( Fields.QUOTA_TOTAL_SIZE != Fields.QUOTA_UNLIMITED )
254+
stats.setTotalQuota( (double) Fields.QUOTA_TOTAL_SIZE / (double) totalSize );
255+
if( Fields.QUOTA_ARCHIVE_LIMIT != Fields.QUOTA_UNLIMITED )
256+
stats.setAvgArchiveCountQuota( (double) Fields.QUOTA_ARCHIVE_LIMIT / stats.getArchivesPerWorkspace() );
257+
195258
// tranfer the results to the main class
196259
quotaManager.workspaceCache = cache;
197260
quotaManager.totalSize = totalSize;
261+
quotaManager.stats = stats;
262+
quotaManager.statsTimestamp = now;
198263

199264
// store settings to disk, if needed
200265
if( storeSettings )
201266
quotaManager.workspaceManager.storeSettings();
202267

203268
LOGGER.info("finished full quota scan");
269+
270+
// save duration of execution
271+
quotaManager.workerExecutionTime = new Date().getTime() - startTime;
204272
// give dobby a sock
205273
quotaManager.workerLock.unlock();
206274
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package de.unirostock.sems.cbarchive.web.dataholder;
2+
3+
import java.io.Serializable;
4+
import java.util.Date;
5+
6+
import com.fasterxml.jackson.annotation.JsonInclude;
7+
import com.fasterxml.jackson.annotation.JsonInclude.Include;
8+
9+
@JsonInclude(Include.NON_DEFAULT)
10+
public class StatisticData implements Serializable {
11+
12+
private static final long serialVersionUID = -3935699299597297002L;
13+
14+
public static final double IGNORE_DOUBLE = -1.0f;
15+
public static final long IGNORE_LONG = -1L;
16+
17+
/** total number of workspaces hosted on this instance */
18+
private long workspaceCount = IGNORE_LONG;
19+
/** total size in bytes of all workspaces combined */
20+
private long totalSize = IGNORE_LONG;
21+
/** average size per workspace */
22+
private double sizePerWorkspace = IGNORE_DOUBLE;
23+
/** average amount of archives per workspace */
24+
private double archivesPerWorkspace = IGNORE_DOUBLE;
25+
/** average age of the workspaces in seconds */
26+
private double avgWorkspaceAge = IGNORE_DOUBLE;
27+
28+
/** relative usage of the total size quota (0.0 - 1.0) */
29+
private double totalQuota = IGNORE_DOUBLE;
30+
/** average usage of space per Workspace quota (0.0 - 1.0) */
31+
private double avgWorkspaceSizeQuota = IGNORE_DOUBLE;
32+
/** average usage of archives per workspace (0.0 - 1.0) */
33+
private double avgArchiveCountQuota = IGNORE_DOUBLE;
34+
35+
/** relative usage of space for the current workspace (0.0 - 1.0) */
36+
private double workspaceSizeQuota = IGNORE_DOUBLE;
37+
/** relative usage of archives per workspace quota (0.0 - 1.0) */
38+
private double archiveCountQuota = IGNORE_DOUBLE;
39+
40+
/** Timestamp of generation */
41+
private Date generated = new Date();
42+
43+
public StatisticData() {}
44+
45+
public long getWorkspaceCount() {
46+
return workspaceCount;
47+
}
48+
49+
public void setWorkspaceCount(long workspaceCount) {
50+
this.workspaceCount = workspaceCount;
51+
}
52+
53+
public long getTotalSize() {
54+
return totalSize;
55+
}
56+
57+
public void setTotalSize(long totalSize) {
58+
this.totalSize = totalSize;
59+
}
60+
61+
public double getSizePerWorkspace() {
62+
return sizePerWorkspace;
63+
}
64+
65+
public void setSizePerWorkspace(double sizePerWorkspace) {
66+
this.sizePerWorkspace = sizePerWorkspace;
67+
}
68+
69+
public double getTotalQuota() {
70+
return totalQuota;
71+
}
72+
73+
public void setTotalQuota(double totalQuota) {
74+
this.totalQuota = totalQuota;
75+
}
76+
77+
public double getAvgWorkspaceSizeQuota() {
78+
return avgWorkspaceSizeQuota;
79+
}
80+
81+
public void setAvgWorkspaceSizeQuota(double avgWorkspaceSizeQuota) {
82+
this.avgWorkspaceSizeQuota = avgWorkspaceSizeQuota;
83+
}
84+
85+
public double getAvgArchiveCountQuota() {
86+
return avgArchiveCountQuota;
87+
}
88+
89+
public void setAvgArchiveCountQuota(double avgArchiveCountQuota) {
90+
this.avgArchiveCountQuota = avgArchiveCountQuota;
91+
}
92+
93+
public double getAvgWorkspaceAge() {
94+
return avgWorkspaceAge;
95+
}
96+
97+
public void setAvgWorkspaceAge(double d) {
98+
this.avgWorkspaceAge = d;
99+
}
100+
101+
public double getWorkspaceSizeQuota() {
102+
return workspaceSizeQuota;
103+
}
104+
105+
public void setWorkspaceSizeQuota(double workspaceSizeQuota) {
106+
this.workspaceSizeQuota = workspaceSizeQuota;
107+
}
108+
109+
public double getArchiveCountQuota() {
110+
return archiveCountQuota;
111+
}
112+
113+
public void setArchiveCountQuota(double archiveCountQuota) {
114+
this.archiveCountQuota = archiveCountQuota;
115+
}
116+
117+
public Date getGenerated() {
118+
return generated;
119+
}
120+
121+
public void setGenerated(Date generated) {
122+
this.generated = generated;
123+
}
124+
125+
public double getArchivesPerWorkspace() {
126+
return archivesPerWorkspace;
127+
}
128+
129+
public void setArchivesPerWorkspace(double archivesPerWorkspace) {
130+
this.archivesPerWorkspace = archivesPerWorkspace;
131+
}
132+
133+
}

0 commit comments

Comments
 (0)