1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package uk.ac.rdg.resc.jstyx.gridservice.server;
30
31 import java.io.InputStream;
32 import java.io.IOException;
33 import java.io.FileNotFoundException;
34 import java.io.File;
35
36 import org.apache.log4j.Logger;
37
38 import uk.ac.rdg.resc.jstyx.server.StyxFile;
39 import uk.ac.rdg.resc.jstyx.server.StyxFileClient;
40 import uk.ac.rdg.resc.jstyx.server.StyxServerProtocolHandler;
41 import uk.ac.rdg.resc.jstyx.messages.RerrorMessage;
42 import uk.ac.rdg.resc.jstyx.StyxException;
43
44 /***
45 * When a client gets data from one of the StyxGridService's data streams (e.g.
46 * out and err), it does so via an instance of this class.
47 * In this class, the entire contents of the stream are written to a file on
48 * the local file system (this file is the cache). Greater performance might be
49 * achieved by caching the data in memory (although the underlying OS will have
50 * its own caching strategy). The performance of this class might be adequate
51 * if the speed of hard disk access is greater than the speed of network traffic,
52 * which is probably a reasonable assumption in most cases.
53 *
54 * @author Jon Blower
55 * $Revision: 286 $
56 * $Date: 2005-05-27 18:05:07 +0100 (Fri, 27 May 2005) $
57 * $Log$
58 * Revision 1.8 2005/05/27 17:05:07 jonblower
59 * Changes to incorporate GeneralCachingStreamReader
60 *
61 * Revision 1.7 2005/05/26 20:31:11 jonblower
62 * Changed behaviour such that clients can start trying to read from the stream before the service is started
63 *
64 * Revision 1.6 2005/05/16 11:00:53 jonblower
65 * Changed SGS config XML file structure: separated input and output streams and changed some tag names
66 *
67 * Revision 1.5 2005/03/24 14:47:47 jonblower
68 * Provided default read() and write() methods for StyxFile so it is no longer abstract
69 *
70 * Revision 1.4 2005/03/24 09:48:31 jonblower
71 * Changed 'count' from long to int throughout for reading and writing
72 *
73 * Revision 1.3 2005/03/21 17:59:49 jonblower
74 * Fixed bug with size of RandomAccessFile
75 *
76 * Revision 1.2 2005/03/18 13:56:00 jonblower
77 * Improved freeing of ByteBuffers, and bug fixes
78 *
79 * Revision 1.1 2005/03/16 22:16:44 jonblower
80 * Added Styx Grid Service classes to core module
81 *
82 * Revision 1.3 2005/03/16 17:59:35 jonblower
83 * Changed following changes to core JStyx library (replacement of java.nio.ByteBuffers with MINA's ByteBuffers)
84 *
85 * Revision 1.2 2005/03/11 09:07:15 jonblower
86 * Changes related to switch from Netty to MINA
87 *
88 * Revision 1.1 2005/02/16 19:22:31 jonblower
89 * Commit adding of SGS files to CVS
90 *
91 */
92 class CachingStreamReader extends StyxFile
93 {
94 private static final Logger log = Logger.getLogger(CachingStreamReader.class);
95
96 private StyxGridServiceInstance sgsInstance;
97 private GeneralCachingStreamReader reader;
98
99 /***
100 * Creates a new CachingStreamReader.
101 * @param inst The StyxGridServiceInstance that owns this CachingStreamReader
102 * @param name The name for this file as it will appear on the Styx server
103 * @throws StyxException if the file could not be created.
104 */
105 public CachingStreamReader(StyxGridServiceInstance inst, String name) throws StyxException
106 {
107 super(name, 0444);
108 this.reader = new SFCachingStreamReader();
109 }
110
111 /***
112 * Sets the input stream from which the CachingStreamReader gets data
113 * and immediately starts reading from this stream
114 * @throws IllegalStateException if this object is already reading from a stream
115 * @throws IOException if the cache file could not be created
116 * and should not happen)
117 */
118 public void startReading(InputStream is) throws IOException
119 {
120 this.reader.startReading(is);
121 }
122
123 public void setCacheFile(File file) throws FileNotFoundException
124 {
125 this.reader.setCacheFile(file);
126 }
127
128 /***
129 * Get data from the stream's cache.
130 * @param offset The offset <b>relative to the start of the whole stream</b> of
131 * the first byte of data requested.
132 * @param count The maximum amount of data to return
133 */
134 public void read(StyxFileClient client, long offset, int count, int tag)
135 throws StyxException
136 {
137 this.reader.read(new SFDataRequest(client, offset, count, tag));
138 }
139
140 private class SFCachingStreamReader extends GeneralCachingStreamReader
141 {
142
143 public void newData(DataRequest originalRequest, byte[] data,
144 int offset, int count)
145 {
146 SFDataRequest dr = (SFDataRequest)originalRequest;
147 StyxFileClient c = (StyxFileClient)dr.client;
148 replyRead(c, data, offset, count, dr.tag);
149 }
150
151 public void error(DataRequest originalRequest, Exception e)
152 {
153 RerrorMessage rErrMsg = new RerrorMessage("error reading from stream: " +
154 e.getMessage());
155 SFDataRequest dr = (SFDataRequest)originalRequest;
156 StyxFileClient c = (StyxFileClient)dr.client;
157 StyxServerProtocolHandler.reply(c.getSession(), rErrMsg, dr.tag);
158 }
159 }
160
161 private static class SFDataRequest extends GeneralCachingStreamReader.DataRequest
162 {
163 private int tag;
164 public SFDataRequest(StyxFileClient client, long offset, int count, int tag)
165 {
166 super(client, offset, count);
167 this.tag = tag;
168 }
169 }
170
171 /***
172 * Called when the file is removed from the server. This deletes the
173 * underlying cache file.
174 */
175 protected synchronized void delete()
176 {
177 this.reader.delete();
178 }
179
180 }