aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/gnunet/requests
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2014-03-11 01:24:03 +0000
committerFlorian Dold <florian.dold@gmail.com>2014-03-11 01:24:03 +0000
commite2eecb019105d48e4afebe1bf57355b3450c8219 (patch)
tree74d8aee60cc6d336a3bb0445af8e091cc2351ecd /src/main/java/org/gnunet/requests
parent651cfb94264b0d12e8ed9afafab05f84d2201933 (diff)
downloadgnunet-java-e2eecb019105d48e4afebe1bf57355b3450c8219.tar.gz
gnunet-java-e2eecb019105d48e4afebe1bf57355b3450c8219.zip
- simplify request containers
- statistics bugs - fix missing annotation in consensus api - work on voting
Diffstat (limited to 'src/main/java/org/gnunet/requests')
-rw-r--r--src/main/java/org/gnunet/requests/MatchingRequestContainer.java87
-rw-r--r--src/main/java/org/gnunet/requests/RequestContainer.java101
-rw-r--r--src/main/java/org/gnunet/requests/SequentialRequestContainer.java181
-rw-r--r--src/main/java/org/gnunet/requests/package-info.java3
4 files changed, 200 insertions, 172 deletions
diff --git a/src/main/java/org/gnunet/requests/MatchingRequestContainer.java b/src/main/java/org/gnunet/requests/MatchingRequestContainer.java
index b2c671e..04b17fd 100644
--- a/src/main/java/org/gnunet/requests/MatchingRequestContainer.java
+++ b/src/main/java/org/gnunet/requests/MatchingRequestContainer.java
@@ -1,3 +1,24 @@
1/*
2 This file is part of GNUnet.
3 (C) 2014 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
21
1package org.gnunet.requests; 22package org.gnunet.requests;
2 23
3import com.google.common.collect.Maps; 24import com.google.common.collect.Maps;
@@ -8,13 +29,13 @@ import java.util.Map;
8 29
9 30
10/** 31/**
11 * Container for requests that are responded to with a matching request identification 32 * Container for requests that are responded to with a matching getRequestIdentifier identification
12 */ 33 */
13public class MatchingRequestContainer<K, T extends RequestContainer.Request> extends RequestContainer { 34public class MatchingRequestContainer<K, T extends Request> extends RequestContainer {
14 /** 35 /**
15 * All queued requests. 36 * All queued requests.
16 */ 37 */
17 private Map<K,T> requests = Maps.newHashMap(); 38 private Map<K,Identifier> requests = Maps.newHashMap();
18 39
19 /** 40 /**
20 * Message queue to send to requests over. 41 * Message queue to send to requests over.
@@ -25,48 +46,48 @@ public class MatchingRequestContainer<K, T extends RequestContainer.Request> ext
25 this.mq = mq; 46 this.mq = mq;
26 } 47 }
27 48
49 private class Identifier extends SimpleRequestIdentifier<T> {
50 final K key;
51
52 public Identifier(T request, K key) {
53 super(request);
54 this.key = key;
55 }
56
57 @Override
58 public void retire() {
59 super.retire();
60 requests.remove(key);
61 }
62 }
63
28 public Cancelable addRequest(K key, final T request) { 64 public Cancelable addRequest(K key, final T request) {
29 if (requests.containsKey(key)) 65 if (requests.containsKey(key))
30 throw new AssertionError("key already present in request container"); 66 throw new AssertionError("key already present in getRequestIdentifier container");
31 requests.put(key, request); 67 Identifier identifier = new Identifier(request, key);
32 mq.send(request.assembleRequest()); 68 requests.put(key, identifier);
33 return new Cancelable() { 69 identifier.send(mq);
34 @Override 70 return identifier;
35 public void cancel() {
36 setRequestCancelled(request);
37 if (isRequestTransmitting(request)) {
38 cancelRequestTransmission(request);
39 } else {
40 request.cancel();
41 }
42 }
43 };
44 } 71 }
45 72
46 @Override 73 @Override
47 public void restart() { 74 public void restart() {
48 Map<K,T> requestsOld = requests; 75 Map<K, Identifier> requestsOld = requests;
49 requests = Maps.newHashMap(); 76 requests = Maps.newHashMap();
50 for (Map.Entry<K,T> e : requestsOld.entrySet()) { 77 for (Map.Entry<K,Identifier> e : requestsOld.entrySet()) {
51 if (!isRequestCancelled(e.getValue())) { 78 addRequest(e.getKey(), e.getValue().getRequest());
52 setRequestTransmitting(e.getValue(), false);
53 addRequest(e.getKey(), e.getValue());
54 }
55 } 79 }
56 } 80 }
57 81
58 public T getRequest(K key) { 82 public RequestIdentifier<T> getRequestIdentifier(K key) {
59 return requests.get(key); 83 return requests.get(key);
60 } 84 }
61 85
62 /** 86 public T getAndRetireRequest(K key) {
63 * Retrieve the request matching the given key, and remove it. 87 RequestIdentifier<T> i = getRequestIdentifier(key);
64 * Return null if there is no matching request. 88 if (null == i)
65 * 89 return null;
66 * @param key key to look for 90 i.retire();
67 * @return request, or null 91 return i.getRequest();
68 */
69 public T pollRequest(K key) {
70 return requests.remove(key);
71 } 92 }
72} 93}
diff --git a/src/main/java/org/gnunet/requests/RequestContainer.java b/src/main/java/org/gnunet/requests/RequestContainer.java
index 8fc631e..9c7fb48 100644
--- a/src/main/java/org/gnunet/requests/RequestContainer.java
+++ b/src/main/java/org/gnunet/requests/RequestContainer.java
@@ -1,90 +1,31 @@
1package org.gnunet.requests; 1/*
2 2 This file is part of GNUnet.
3 (C) 2014 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
3 20
4import org.gnunet.mq.Envelope; 21package org.gnunet.requests;
5import org.gnunet.util.Cancelable;
6 22
7/** 23/**
8 * Container for requests to a service. 24 * Container for requests to a service.
9 */ 25 */
10public abstract class RequestContainer { 26public abstract class RequestContainer {
11 /** 27 /**
12 * Do we allow sending pending requests while 28 * Re-send all active and pending requests.
13 * other requests are still active (true), or do we send
14 * requests one-by-one (false)?
15 */
16 protected boolean overlap = true;
17
18 /**
19 * A request that can be put in a request container.
20 */
21 public abstract static class Request {
22 private boolean transmitting;
23 private boolean canceled;
24 private Cancelable cancelRequest;
25
26 /**
27 * Create an envelope for executing the request.
28 *
29 * @return Envelope to be sent to the service with the request message.
30 */
31 public abstract Envelope assembleRequest();
32
33 /**
34 * Implement cancellation logic for requests.
35 * Only called when the request has already been sent to the service.
36 *
37 * By default, canceling a request throws an exception.
38 */
39 public void cancel() {
40 throw new AssertionError("request of type " + this.getClass() + " can not be canceled (not implemented)");
41 }
42 }
43
44 /**
45 * Re-send all requests in the queue that have not been canceled.
46 */ 29 */
47 public abstract void restart(); 30 public abstract void restart();
48
49 /**
50 * Allow or disallow requests to be send while other requests in the queue have not been completed.
51 *
52 * @param overlap true to allow overlapped requests, false to disallow them
53 */
54 public void setOverlap(boolean overlap) {
55 this.overlap = overlap;
56 }
57
58 /**
59 * Check if the given request is transmitting, that is, the request
60 * is waiting to be sent to the service.
61 *
62 * @param r request
63 * @return whether the request is still being transmitted
64 */
65 protected boolean isRequestTransmitting(Request r) {
66 return r.transmitting;
67 }
68
69 protected void setRequestTransmitting(Request r, boolean transmitting) {
70 r.transmitting = transmitting;
71 }
72
73 protected void setRequestTransmissionCancel(Request request, Cancelable cancel) {
74 request.cancelRequest = cancel;
75 }
76
77 protected void cancelRequestTransmission(Request r) {
78 r.cancelRequest.cancel();
79 r.cancelRequest = null;
80 }
81
82 protected void setRequestCancelled(Request r) {
83 r.canceled = true;
84 }
85
86 protected boolean isRequestCancelled(Request r) {
87 return r.canceled;
88 }
89
90} 31}
diff --git a/src/main/java/org/gnunet/requests/SequentialRequestContainer.java b/src/main/java/org/gnunet/requests/SequentialRequestContainer.java
index 037055f..c343812 100644
--- a/src/main/java/org/gnunet/requests/SequentialRequestContainer.java
+++ b/src/main/java/org/gnunet/requests/SequentialRequestContainer.java
@@ -1,86 +1,153 @@
1/*
2 This file is part of GNUnet.
3 (C) 2014 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19 */
20
1package org.gnunet.requests; 21package org.gnunet.requests;
2 22
3import org.gnunet.mq.Envelope;
4import org.gnunet.mq.MessageQueue; 23import org.gnunet.mq.MessageQueue;
5import org.gnunet.mq.NotifySentHandler;
6import org.gnunet.util.Cancelable;
7 24
8import java.util.LinkedList; 25import java.util.LinkedList;
9 26
10/** 27/**
11 * Container for requests that are responded to in sequential order. 28 * Container for requests that are responded to in sequential order.
12 */ 29 */
13public class SequentialRequestContainer<T extends RequestContainer.Request> extends RequestContainer { 30public class SequentialRequestContainer<T extends Request> extends RequestContainer {
14 private LinkedList<T> requests = new LinkedList<T>(); 31 /**
15 private MessageQueue mq; 32 * Allow overlapping requests.
33 */
34 private boolean overlap;
35 /**
36 * Request in our queue with information about them.
37 */
38 private LinkedList<Identifier> requests = new LinkedList<Identifier>();
39 /**
40 * Message queue that is used to send envelopes.
41 */
42 private final MessageQueue mq;
16 43
17 int requestsActive = 0; 44 /**
45 * Number of active requests.
46 */
47 private int requestsActive = 0;
18 48
19 public SequentialRequestContainer(MessageQueue mq) { 49 /**
50 * Create a sequential request container that sends messages with the given
51 * message queue.
52 *
53 * @param mq message queue to send messages with
54 * @param overlap allow sending requests while other request have not yet completed
55 */
56 public SequentialRequestContainer(MessageQueue mq, boolean overlap) {
20 this.mq = mq; 57 this.mq = mq;
58 this.overlap = overlap;
59 }
60 /**
61 * Create a sequential request container that sends messages with the given
62 * message queue. Do not allow other requests to be send while the current request
63 * is still active.
64 *
65 * @param mq message queue to send messages with
66 */
67 public SequentialRequestContainer(MessageQueue mq) {
68 this(mq, false);
69 }
70 /**
71 * Get the current request's identifier.
72 *
73 * @return current request
74 */
75 public RequestIdentifier<T> getRequestIdentifier() {
76 return requests.peekFirst();
21 } 77 }
22 78
79 /**
80 * Get the current request and retire it.
81 * If there is no current request, null will be returned.
82 *
83 * @return current request
84 */
85 public T getAndRetireRequest() {
86 RequestIdentifier<T> i = getRequestIdentifier();
87 if (null == i)
88 return null;
89 i.retire();
90 return i.getRequest();
91 }
92
93 public Iterable<RequestIdentifier<T>> iter() {
94 return (Iterable) requests;
95 }
96
97 /**
98 * Get the current request.
99 *
100 * @return the current request.
101 */
23 public T getRequest() { 102 public T getRequest() {
24 return requests.getFirst(); 103 RequestIdentifier<T> i = getRequestIdentifier();
104 if (null == i)
105 return null;
106 return i.getRequest();
25 } 107 }
26 108
27 public void next() { 109 /**
28 if (requestsActive == 0 || requests.isEmpty()) 110 * A request identifier in a sequential request container.
29 throw new AssertionError(); 111 */
30 requestsActive--; 112 private class Identifier extends SimpleRequestIdentifier<T> {
31 requests.removeFirst(); 113 public Identifier(T request) {
32 if (requestsActive == 0 && !requests.isEmpty()) { 114 super(request);
33 Request r = requests.getFirst(); 115 }
34 setRequestTransmitting(r, true); 116
35 Envelope ev = r.assembleRequest(); 117 @Override
36 setRequestTransmissionCancel(r, ev); 118 public void retire() {
37 mq.send(r.assembleRequest()); 119 super.retire();
38 requestsActive++; 120 if (requestsActive == 0 || requests.isEmpty())
121 throw new AssertionError();
122 boolean found = requests.remove(this);
123 if (!found)
124 throw new AssertionError("request not in queue");
125 requestsActive--;
126 Identifier next = requests.peekFirst();
127 if (null == next || next.queued)
128 return;
129 if (requestsActive == 0 || overlap)
130 next.send(mq);
39 } 131 }
40 } 132 }
41 133
42 public Cancelable addRequest(final T request) { 134 public RequestIdentifier<T> addRequest(final T request) {
43 requests.addLast(request); 135 final Identifier identifier = new Identifier(request);
136 requests.addLast(identifier);
137 // only send immediately if we are allowed to
44 if (overlap || requestsActive == 0) { 138 if (overlap || requestsActive == 0) {
45 requestsActive++; 139 identifier.send(mq);
46 setRequestTransmitting(request, true); 140 requestsActive += 1;
47 Envelope ev = request.assembleRequest();
48 ev.notifySent(new NotifySentHandler() {
49 @Override
50 public void onSent() {
51 setRequestTransmitting(request, false);
52 }
53 });
54 setRequestTransmissionCancel(request, ev);
55 mq.send(request.assembleRequest());
56 } 141 }
57 return new Cancelable() { 142 return identifier;
58 @Override
59 public void cancel() {
60 setRequestCancelled(request);
61 if (isRequestTransmitting(request)) {
62 cancelRequestTransmission(request);
63 } else {
64 request.cancel();
65 }
66 }
67 };
68 } 143 }
69 144
70 @Override 145 @Override
71 public void restart() { 146 public void restart() {
72 LinkedList<T> requestsOld = requests; 147 LinkedList<Identifier> requestsOld = requests;
73 requests = new LinkedList<T>(); 148 requests = new LinkedList<Identifier>();
74 for (T r : requestsOld) { 149 for (Identifier r : requestsOld) {
75 if (!isRequestCancelled(r)) { 150 addRequest(r.getRequest());
76 setRequestTransmitting(r, false);
77 addRequest(r);
78 }
79 } 151 }
80 } 152 }
81
82
83 public Iterable<T> iter() {
84 return requests;
85 }
86} 153}
diff --git a/src/main/java/org/gnunet/requests/package-info.java b/src/main/java/org/gnunet/requests/package-info.java
index 892a606..b4fd674 100644
--- a/src/main/java/org/gnunet/requests/package-info.java
+++ b/src/main/java/org/gnunet/requests/package-info.java
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 (C) 2011, 2012 Christian Grothoff (and other contributing authors) 3 (C) 2014 Christian Grothoff (and other contributing authors)
4 4
5 GNUnet is free software; you can redistribute it and/or modify 5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published 6 it under the terms of the GNU General Public License as published
@@ -18,7 +18,6 @@
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19 */ 19 */
20 20
21
22/** 21/**
23 * General mechanism for queueing requests to a service. 22 * General mechanism for queueing requests to a service.
24 */ 23 */