Changeset 71
- Timestamp:
- 05/15/05 16:33:11 (4 years ago)
- Files:
-
- trunk/dsp/ConfigParser.d (modified) (4 diffs)
- trunk/dsp/DSPProcessor.d (modified) (1 diff)
- trunk/dsp/DSPTag.d (modified) (1 diff)
- trunk/dsp/ServletCompiler.d (modified) (2 diffs)
- trunk/dsp/ServletGenerator.d (modified) (1 diff)
- trunk/dsp/TagLibrary.d (modified) (1 diff)
- trunk/dsp/Util.d (modified) (2 diffs)
- trunk/dsp/servlet/DSPServlet.d (modified) (12 diffs)
- trunk/dsp/servlet/DSPServletProvider.d (modified) (2 diffs)
- trunk/dsp/tags/Code.d (modified) (1 diff)
- trunk/dsp/tags/InCode.d (modified) (1 diff)
- trunk/dsp/tags/OutCode.d (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/dsp/ConfigParser.d
r67 r71 26 26 module dsp.ConfigParser; 27 27 28 private import xml.XMLException; 29 private import xml.XMLAttributes; 30 private import xml.IXMLConsumerAdapter; 31 private import xml.XMLParser; 32 private import xml.ILexerStream; 28 private import xml.utf8all; 33 29 34 30 private import mango.http.utils.Dictionary; 35 31 private import mango.io.model.IConduit; 32 private import mango.io.model.IBuffer; 33 private import mango.io.Buffer; 34 private import mango.io.Tokenizer; 36 35 37 36 private import std.utf; … … 74 73 uint state; 75 74 76 public MutableDictionary parse(ILexerStream stream){ 75 static const uint DEFAULT_CAPACITY = 1024; 76 77 class CompleteBufferReader: Scanner{ 78 IBuffer buffer; 79 80 this(IBuffer buffer){ 81 this.buffer = buffer; 82 } 83 84 char[] read(){ 85 char[] data; 86 87 // delegate to read in everything that is passed in 88 int scan (char[] content) 89 { 90 data ~= content; 91 return IConduit.Eof; 92 } 93 super.next (buffer, &scan); 94 return(data); 95 } 96 } 97 98 public MutableDictionary parse(IConduit conduit){ 99 IBuffer buf = new Buffer(DEFAULT_CAPACITY); 100 buf.setConduit(conduit); 101 102 CompleteBufferReader reader = new CompleteBufferReader(buf); 77 103 dictionary = new MutableDictionary(); 78 text = ""; 79 name = ""; 80 state = Root; 81 82 XMLParser parser = new XMLParser(); 83 parser.parse(this,stream); 84 104 105 XMLParser parser = new XMLParser(); 106 parser.parse(this,charTConvert(reader.read())); 85 107 return dictionary; 86 } 87 108 } 109 88 110 void xmlStartElement(char[] name,XMLAttributes attribs,bit isEmpty){ 89 111 switch(state){ … … 102 124 this.name = name; 103 125 } 104 126 105 127 if("value" in attribs){ 106 128 dictionary.put(name,attribs["value"]); … … 140 162 } 141 163 142 void xmlText(char[] text ){164 void xmlText(char[] text,uint type){ 143 165 switch(state){ 144 166 case Root: trunk/dsp/DSPProcessor.d
r67 r71 33 33 34 34 35 private import xml.IXMLConsumerAdapter; 36 private import xml.XMLAttributes; 35 private import xml.utf8all; 37 36 38 37 private import std.stdio; 39 38 private import std.string; 40 39 41 class DSPProcessor : IXMLConsumerAdapter{40 class DSPProcessor : SimpleConsumer{ 42 41 ServletGenerator generator; 43 42 TagLibrary tags; trunk/dsp/DSPTag.d
r48 r71 26 26 module dsp.DSPTag; 27 27 28 private import xml. XMLAttributes;28 private import xml.utf8all; 29 29 30 30 private import dsp.ServletGenerator; trunk/dsp/ServletCompiler.d
r68 r71 30 30 private import dsp.RequestConfig; 31 31 32 private import xml. all;32 private import xml.utf8all; 33 33 34 34 private import std.file; … … 56 56 57 57 private void ProcessDSPFile(RequestConfig cfg){ 58 char[] source = strip(toUTF8(cast(char[])std.file.read(cfg.dspSourceFilename)));58 CharT[] source = charTConvert(cast(char[])std.file.read(cfg.dspSourceFilename)); 59 59 60 SimpleStream stream = new SimpleStream(source); 61 62 parser.parse(processor, provider, stream); 60 parser.parse(processor, provider, source); 63 61 std.file.write(cfg.dSourceFilename,cast(char[])processor.getServletSource(cfg.requestModule,cfg.ext)); 64 62 } trunk/dsp/ServletGenerator.d
r67 r71 135 135 } 136 136 else{ 137 expression ~= " ~ " ~ thisPart;137 expression ~= " ~ " ~ DSPGrammar.toStringFunc ~ "(" ~ thisPart ~ ")"; 138 138 } 139 139 } trunk/dsp/TagLibrary.d
r48 r71 26 26 module dsp.TagLibrary; 27 27 28 private import xml. XMLAttributes;28 private import xml.utf8all; 29 29 30 30 private import dsp.ServletGenerator; trunk/dsp/Util.d
r48 r71 38 38 int pos = 0; 39 39 40 debug printf("split: %.*s\n",src); 41 debug printf("src: '%*.s'\n",src); 40 42 while(lastPos < src.length){ 41 43 pos = find(src[lastPos..$],delim); 42 pos += lastPos;43 44 if(pos == -1){ 44 45 result ~= src[lastPos..$]; … … 46 47 } 47 48 else{ 48 result ~= src[lastPos..pos]; // get segment 49 pos += lastPos; 50 debug printf("last %d, pos: %d\n",lastPos,pos); 51 if(pos == 0) result ~= ""; 52 else result ~= src[lastPos..pos]; // get segment 49 53 result ~= src[pos..pos + delim.length]; // keep the delimiter 50 54 lastPos = pos + delim.length; // advance 51 55 } 52 56 } 57 printf("\n"); 53 58 return result; 54 59 } trunk/dsp/servlet/DSPServlet.d
r67 r71 38 38 private import dsp.RequestConfig; 39 39 40 private import mango.cache.Payload; 41 private import mango.cache.QueuedCache; 40 private import mango.cache.HashMap; 42 41 43 42 private import mango.servlet.Servlet; … … 60 59 //TODO: use SystemFinalizer to catch libraries that are still loaded at shutdown 61 60 62 class DSPLibrary : Payload{61 class DSPLibrary{ 63 62 protected long timeModified; 64 63 protected Library lib; 65 64 public ServiceHandle service; 66 65 protected DependencyHandle dependencies; 66 67 public DSPLibrary next,last; 68 public char[] key; 67 69 68 70 protected void unload(){ 69 debug printf("unloading library\n"); 70 lib.unload(); 71 lib = null; 72 service = null; 73 dependencies = null; 74 timeModified = 0; 71 if(lib){ 72 debug printf("unloading library %.*s\n",lib.getPath()); 73 if(lib.isLoaded) lib.unload(); 74 lib = null; 75 service = null; 76 dependencies = null; 77 timeModified = 0; 78 } 79 } 80 81 public char[] getPath(){ 82 if(lib && lib.isLoaded) return lib.getPath(); 83 return "[not loaded]"; 75 84 } 76 85 … … 91 100 throw new DSPException("servlet library does not have a valid dependencies handle"); 92 101 } 102 103 debug printf("library loaded: %.*s\n",path); 93 104 } 94 105 else{ … … 107 118 // verify the date/time of the dependencies 108 119 foreach(char[] dep; dependencies()){ 109 debug printf("[%.*s%.*s]\n",basePath,dep);120 debug debug printf("[%.*s%.*s]\n",basePath,dep); 110 121 if((new FileProxy(basePath ~ dep)).getModifiedTime() > timeModified){ 111 debug printf("%.*s%.*s : servlet is out of date.\n",basePath,dep); 112 unload(); // force unload 122 debug printf("%.*s%.*s : servlet is out of date.\n",basePath,dep); 113 123 return true; 114 124 } … … 118 128 119 129 return false; 120 }121 122 void destroy (){123 printf("library: %.*s destroyed\n",lib.getPath);124 unload();125 130 } 126 131 … … 137 142 } 138 143 } 144 145 146 class DSPLibraryCache{ 147 HashMap map; 148 DSPLibrary mostPopular,leastPopular; // mp through last pointers to lp. lp through next opinters to mp. 149 uint freeCount; 150 151 this (uint capacity = 101, uint concurrency = 16){ 152 map = new HashMap (capacity, 0.75, concurrency); 153 mostPopular = null; 154 leastPopular = null; 155 freeCount = capacity; 156 } 157 158 protected void dropEntry(DSPLibrary lib){ 159 debug printf("dropEntry\n"); 160 if(lib.next) lib.next.last = lib.last; 161 if(lib.last) lib.last.next = lib.next; 162 if(lib is mostPopular){ 163 mostPopular = mostPopular.last; 164 if(mostPopular){ 165 mostPopular.last = null; 166 } 167 } 168 if(lib is leastPopular){ 169 leastPopular = leastPopular.next; 170 if(leastPopular){ 171 leastPopular.last = null; 172 } 173 } 174 } 175 176 protected void makePopular(DSPLibrary lib){ 177 debug printf("makePopular\n"); 178 dropEntry(lib); 179 if(mostPopular is null){ 180 mostPopular = lib; 181 leastPopular = lib; 182 } 183 else if(!(lib is mostPopular)){ 184 mostPopular.next = lib; 185 lib.last = mostPopular; 186 mostPopular = lib; 187 } 188 } 189 190 protected void dropLeastPopular(){ 191 debug printf("dropLeastPopular\n"); 192 if(leastPopular){ 193 leastPopular.unload(); 194 leastPopular = leastPopular.next; 195 if(leastPopular){ 196 leastPopular.last = null; 197 } 198 } 199 } 200 201 void put(char[] path,DSPLibrary lib){ 202 // place entry in the queue 203 if(lib){ 204 assert(!map.containsKey(path.dup)); 205 206 lib.key = path.dup; // set the key for future use 207 208 if(freeCount == 0){ 209 //replace oldest cache entry and free the replaced entry 210 map.remove(leastPopular.key); 211 synchronized(this){ 212 dropLeastPopular(); 213 makePopular(lib); 214 } 215 } 216 else{ 217 synchronized(this) makePopular(lib); 218 freeCount--; 219 } 220 221 // place the entry in the map 222 map.put(lib.key,lib); 223 } 224 225 // remove the entry from the queue 226 else{ 227 Object obj = map.remove(path); 228 if(obj){ 229 DSPLibrary lib = cast(DSPLibrary)obj; 230 //remove this entry from the list 231 synchronized(this){ 232 dropEntry(lib); 233 } 234 freeCount++; 235 } 236 } 237 } 238 239 DSPLibrary get(char[] path){ 240 Object obj = map.get(path); 241 if(obj){ 242 DSPLibrary lib = cast(DSPLibrary)obj; 243 synchronized(this) makePopular(lib); 244 return lib; 245 } 246 return null; 247 } 248 249 char[] toString(){ 250 char[] output = ""; 251 DSPLibrary current = leastPopular; 252 uint i; 253 while(current){ 254 output ~= "- " ~ current.getPath() ~ "\n"; 255 current = current.next; 256 i++; 257 if(i == 100) return "[possible infinite recursion on linked-list]\n"; 258 } 259 return output; 260 } 261 } 262 139 263 140 264 /* … … 154 278 class DSPServlet : Servlet{ 155 279 private static Logger logger; 156 protected QueuedCache cache;280 protected DSPLibraryCache cache; 157 281 158 282 static this (){ … … 170 294 libraryPath ~= path.getName[1..$] ~ ".dll"; 171 295 172 debug printf("attempting to recover: %.*s\n",libraryPath);296 debug debug printf("attempting to recover: %.*s\n",libraryPath); 173 297 174 298 //TODO: check for file existence here or not? … … 178 302 179 303 // catch-all here as the library may not be in a usable condition 180 //TODO: eliminate the library from the cache if it exists?181 304 catch(Exception e){ 182 305 return null; … … 218 341 219 342 // debug 220 debug printf("%.*s\n",cfg.toString());343 debug debug printf("%.*s\n",cfg.toString()); 221 344 222 345 // build the servlet library … … 248 371 DSPLibrary lib = cast(DSPLibrary)cache.get(request.getPathInfo); 249 372 250 if(lib){ 251 printf("cache lib: %.*s = %.*s\n",request.getPathInfo,lib.toString()); 252 } 253 else{ 254 printf("cache lib: %.*s = [not present]\n",request.getPathInfo); 373 debug{ 374 if(lib){ 375 printf("cache lib: %.*s = %.*s\n",request.getPathInfo,lib.toString()); 376 } 377 else{ 378 printf("cache lib: %.*s = [not present]\n",request.getPathInfo); 379 } 255 380 } 256 381 257 382 // attempt to recover the lib from the file cache 258 383 if(!lib){ 259 cache.extract(request.getPathInfo); // kill the cache entry260 384 lib = recoverLibrary(context,path); 261 if(lib){ 262 cache.put(request.getPathInfo,lib); 263 } 385 cache.put(request.getPathInfo,lib); // update the cache with new or empty lib 264 386 } 265 387 266 388 // rebuild the library if recovery fails or is out of date 267 if(!lib || lib.isOutOfDate(context.getBasePath,path)){389 if(!lib){ 268 390 lib = buildLibrary(context,path); 269 cache.put(request.getPathInfo,lib); 391 cache.put(request.getPathInfo,lib); // update the cache 392 } 393 else if(lib.isOutOfDate(context.getBasePath,path)){ 394 lib.unload(); 395 cache.put(request.getPathInfo,null); // remove the old entry 396 lib = buildLibrary(context,path); 397 cache.put(request.getPathInfo,lib); // update the cache 270 398 } 271 399 272 400 // run the servlet 273 lib.service(dspRequest,dspResponse); 274 401 if(lib){ 402 lib.service(dspRequest,dspResponse); 403 } 404 else{ 405 //TODO: report failure to build library 406 } 407 408 debug printf("Cache:\n%.*s",cache.toString()); 275 409 //TODO: debug information 276 410 } … … 308 442 debug printf("(cache config) size: %d threads: %d\n",size,threads); 309 443 310 cache = new QueuedCache(size,threads);444 cache = new DSPLibraryCache(size,threads); 311 445 } 312 446 } trunk/dsp/servlet/DSPServletProvider.d
r67 r71 25 25 26 26 module dsp.servlet.DSPServletProvider; 27 28 private import xml.ConduitStream;29 27 30 28 private import dsp.ConfigParser; … … 57 55 // load configuration 58 56 if(fc){ 59 ConduitStream cs = new ConduitStream(fc.getPath.getName,fc);60 57 ConfigParser configParser = new ConfigParser(); 61 configuration = configParser.parse( cs);58 configuration = configParser.parse(fc); 62 59 } 63 60 } trunk/dsp/tags/Code.d
r48 r71 26 26 module dsp.tags.Code; 27 27 28 private import xml. XMLAttributes;28 private import xml.utf8all; 29 29 30 30 private import dsp.ServletGenerator; trunk/dsp/tags/InCode.d
r48 r71 26 26 module dsp.tags.InCode; 27 27 28 private import xml. XMLAttributes;28 private import xml.utf8all; 29 29 30 30 private import dsp.ServletGenerator; trunk/dsp/tags/OutCode.d
r48 r71 26 26 module dsp.tags.OutCode; 27 27 28 private import xml. XMLAttributes;28 private import xml.utf8all; 29 29 30 30 private import dsp.ServletGenerator;
