source: src/main/java/geniusweb/runserver/PartyConnectionFactory.java@ 8

Last change on this file since 8 was 7, checked in by bart, 5 years ago

Release 1.1.0

File size: 4.6 KB
Line 
1package geniusweb.runserver;
2
3import java.io.IOException;
4import java.net.URI;
5import java.net.URISyntaxException;
6import java.util.Date;
7import java.util.HashMap;
8import java.util.LinkedList;
9import java.util.List;
10import java.util.Map;
11import java.util.Set;
12import java.util.logging.Level;
13
14import geniusweb.protocol.partyconnection.ProtocolToPartyConn;
15import geniusweb.protocol.partyconnection.ProtocolToPartyConnFactory;
16import geniusweb.references.PartyRef;
17import geniusweb.references.Reference;
18import tudelft.utilities.logging.Reporter;
19import tudelft.utilities.repository.NoResourcesNowException;
20
21/**
22 * Factory conform ConnectionWithPartyFactory based on HTTP calls and websockets
23 * following the partiesserver protocols.
24 */
25class PartyConnectionFactory implements ProtocolToPartyConnFactory {
26 private final Reporter log;
27
28 /**
29 * @param logger the logger used for all created connections as well as for
30 * failed attempts to connect.
31 */
32 public PartyConnectionFactory(Reporter logger) {
33 this.log = logger;
34 }
35
36 @Override
37 public WebSocketProtToPartyConn connect(Reference reference)
38 throws IOException, NoResourcesNowException {
39 try {
40 return new WebSocketProtToPartyConn(reference, log).init();
41 } catch (IOException e) {
42 Date date = getWaitingTime(e);
43 if (date == null)
44 throw e;
45 throw new NoResourcesNowException("No resources for " + reference,
46 date);
47 }
48 }
49
50 /**
51 * This is a specific implementation that uses a simple modified Banker's
52 * algorithm.
53 *
54 * @throws NoResourcesNowException if one party can not be allocated,
55 * failing with a
56 * {@link NoResourcesNowException}. In this
57 * case all resources that were allocated
58 * while the attempt was done are freed up.
59 */
60
61 @Override
62 public List<ProtocolToPartyConn> connect(List<Reference> references)
63 throws IOException, NoResourcesNowException {
64 /*
65 * FIXME Check first. If request is impossible, we should throw a
66 * ProtocolException instead of keeping failing with
67 * NoResourcesNowException. This implementation will cause a life lock
68 * in a session or tournament with impossible settings (eg more parties
69 * than slots on the partiesserver).
70 */
71 log.log(Level.INFO, "attempting to connect " + references);
72 List<ProtocolToPartyConn> connections = new LinkedList<>();
73 try {
74 for (Reference partyref : references) {
75 ProtocolToPartyConn conn = null;
76 while (conn == null) {
77 try {
78 conn = connect(partyref);
79 } catch (IOException e) {
80 throw new IOException(
81 "Failed to connect to " + partyref.toString(),
82 e);
83 }
84 }
85 connections.add(conn);
86 }
87 } catch (IOException | NoResourcesNowException e) {
88 // free all already created connections
89 for (ProtocolToPartyConn conn : connections) {
90 conn.close();
91 }
92 throw e;
93 }
94 log.log(Level.INFO, "succesfully connected " + references);
95 return connections;
96 }
97
98 /**
99 * Try to get a suggested wait time out of the IOException.
100 *
101 * Sometiems the IOException itself contains already the text "please retry
102 * later".
103 *
104 *
105 * @param e the {@link IOException} that may contain extra information
106 * @return a Date contained in the IOException
107 */
108 private Date getWaitingTime(IOException e) {
109 String msg = e.getMessage();
110 if (msg.contains("retry later")) {
111 long suggestedRetryTime = -1;
112 try {
113 String[] elements = msg.split(" ");
114 suggestedRetryTime = Long
115 .parseLong(elements[elements.length - 1]);
116 } catch (NumberFormatException e1) {
117 // silent catch, we check the value and report errors below.
118 }
119 if (suggestedRetryTime < 0) {
120 log.log(Level.WARNING,
121 "Server 503 message does not contain proper positive long as last value:"
122 + msg,
123 e);
124 suggestedRetryTime = System.currentTimeMillis() + 5000;
125 }
126 return new Date(suggestedRetryTime);
127 }
128 return null;
129 }
130
131 private Map<URI, Set<Reference>> groupByServer(List<Reference> references) {
132 Map<URI, Set<Reference>> map = new HashMap<>();
133 for (Reference ref : references) {
134
135 }
136 return map;
137
138 }
139
140 /**
141 * Get the base uri of a Reference (http://base./../..) from a ref like
142 * http://base../run/<somepartyname>
143 *
144 * @param ref the reference to extract base URI from
145 * @return URI holding the base name of the server
146 */
147 private URI getBaseURI(PartyRef ref) {
148 String str = ref.getURI().toString();
149 try {
150 return new URI(str.substring(0, str.indexOf("/run/")));
151 } catch (URISyntaxException e) {
152 e.printStackTrace(); // straight bug
153 return null;
154 }
155 }
156}
Note: See TracBrowser for help on using the repository browser.