1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.tests.api.request.misc;
14 import java.util.concurrent.atomic.AtomicInteger;
16 import org.junit.Test;
17 import org.simantics.db.AsyncReadGraph;
18 import org.simantics.db.ReadGraph;
19 import org.simantics.db.Session;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.db.procedure.AsyncListener;
22 import org.simantics.db.procedure.AsyncProcedure;
23 import org.simantics.db.request.AsyncRead;
24 import org.simantics.db.request.Read;
25 import org.simantics.db.service.QueryControl;
26 import org.simantics.db.service.QueryControl.ControlProcedure;
27 import org.simantics.db.testing.base.ExistingDatabaseTest;
29 public class RequestQueuingTest extends ExistingDatabaseTest {
31 final private static int LOOPS = 10;
33 private Object RESULT = new Object();
34 private DatabaseException EXCEPTION = new DatabaseException();
36 private AtomicInteger results = new AtomicInteger(0);
37 private AtomicInteger exceptions = new AtomicInteger(0);
39 class A implements AsyncRead<Object> {
41 private void perform(AsyncReadGraph graph, final AsyncProcedure<Object> procedure, final int todo) {
45 procedure.execute(graph, RESULT);
49 final QueryControl control = graph.getService(QueryControl.class);
50 final int current = control.getGraphThread(graph);
51 final int next = (current + 1) % control.getAmountOfQueryThreads();
52 control.schedule(graph, next, new ControlProcedure() {
54 public void execute(AsyncReadGraph graph) {
55 perform(graph, procedure, todo-1);
66 public void perform(AsyncReadGraph graph, final AsyncProcedure<Object> procedure) {
67 perform(graph, procedure, 5);
71 public int threadHash() {
76 public int getFlags() {
82 class B implements Read<Object> {
85 public Object perform(ReadGraph graph) throws DatabaseException {
87 return graph.syncRequest(new A());
93 class A2 implements AsyncRead<Object> {
95 private void perform(AsyncReadGraph graph, final AsyncProcedure<Object> procedure, final int todo) {
99 procedure.exception(graph, EXCEPTION);
103 final QueryControl control = graph.getService(QueryControl.class);
104 final int current = control.getGraphThread(graph);
105 final int next = (current + 1) % control.getAmountOfQueryThreads();
106 control.schedule(graph, next, new ControlProcedure() {
108 public void execute(AsyncReadGraph graph) {
109 perform(graph, procedure, todo-1);
120 public void perform(AsyncReadGraph graph, final AsyncProcedure<Object> procedure) {
121 perform(graph, procedure, 5);
125 public int threadHash() {
130 public int getFlags() {
136 class B2 implements Read<Object> {
139 public Object perform(ReadGraph graph) throws DatabaseException {
141 return graph.syncRequest(new A2());
147 class C implements AsyncListener<Object> {
150 public void execute(AsyncReadGraph graph, Object result) {
151 if(RESULT == result) results.incrementAndGet();
155 public void exception(AsyncReadGraph graph, Throwable throwable) {
156 if(EXCEPTION == throwable) exceptions.incrementAndGet();
160 public boolean isDisposed() {
167 public void test() throws Exception {
169 Session session = getSession();
171 session.syncRequest(new Read<Object>() {
174 public Object perform(ReadGraph graph) throws DatabaseException {
180 for(int i=0;i<LOOPS;i++) graph.asyncRequest(a, new C());
181 for(int i=0;i<LOOPS;i++) graph.asyncRequest(a2, new C());
182 for(int i=0;i<LOOPS;i++) graph.asyncRequest(b, new C());
183 for(int i=0;i<LOOPS;i++) graph.asyncRequest(b2, new C());
191 if(results.get() != 2*LOOPS) fail("Incorrect amount of reported results (expected " + 2*LOOPS + ", got " + results.get() + ")");
192 if(exceptions.get() != 2*LOOPS) fail("Incorrect amount of reported exceptions (expected " + 2*LOOPS + ", got " + exceptions.get() + ")");