1 /* 2 * The MIT License (MIT) 3 * 4 * Copyright (c) 2014 Richard Andrew Cattermole 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to deal 8 * in the Software without restriction, including without limitation the rights 9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 * copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in all 14 * copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 module dakka.base.impl.local; 25 import dakka.base.impl.defs; 26 import dakka.base.defs; 27 28 pure string generateFuncLocalHandler(T : Actor, string m)() { 29 import std.traits : ReturnType; 30 enum T t = T.init; 31 32 string ret; 33 ret ~= " synchronized(localRef) {\n"; 34 35 ret ~= " if(supervisor !is null && !isAlive_) {\n"; 36 ret ~= " if ((supervisor.isLocalInstance && supervisor.isAlive_ && !supervisor.isDying_) || (!supervisor.isLocalInstance && getDirector().validAddressIdentifier((cast(ActorRef!(Actor))supervisor).remoteAddressIdentifier))) {\n"; 37 ret ~= " (cast()supervisor).onChildError(this, \"Node instance is on a remote server. But it has been disconnected.\");\n"; 38 ret ~= " } else {\n"; 39 ret ~= " die();\n"; 40 ret ~= " }\n"; 41 ret ~= " }\n"; 42 43 static if (hasReturnValue!(T, m)) { 44 // this shouldn't be pushed into a new thread. Blocks because we have a return type. 45 ret ~= " try {\n"; 46 ret ~= " return localRef." ~ m ~ "(" ~ generateFuncCall!(T, m) ~ ");\n"; 47 ret ~= " } catch(Exception e) {\n"; 48 ret ~= " if(supervisor !is null) {\n"; 49 ret ~= " if (supervisor.isLocalInstance || (!supervisor.isLocalInstance && getDirector().validAddressIdentifier((cast(ActorRef!(Actor))supervisor).remoteAddressIdentifier))) {\n"; 50 ret ~= " (cast()supervisor).onChildError(this, e.toString());\n"; 51 ret ~= " } else {\n"; 52 ret ~= " die();\n"; 53 ret ~= " }\n"; 54 ret ~= " }\n"; 55 ret ~= " return " ~ typeText!(ReturnType!(mixin("t." ~ m))) ~ ".init;\n"; 56 ret ~= " }\n"; 57 } else { 58 // with a void return type, we want to push this into another thread. Asynchronous because we don't have a return type. No point blocking is there? 59 ret ~= " runTask({\n"; 60 ret ~= " try {\n"; 61 ret ~= " localRef." ~ m ~ "(" ~ generateFuncCall!(T, m) ~ ");\n"; 62 ret ~= " } catch(Exception e) {\n"; 63 ret ~= " if(supervisor !is null) {\n"; 64 ret ~= " if (supervisor.isLocalInstance || (!supervisor.isLocalInstance && getDirector().validAddressIdentifier((cast(ActorRef!(Actor))supervisor).remoteAddressIdentifier))) {\n"; 65 ret ~= " (cast()supervisor).onChildError(this, e.toString());\n"; 66 ret ~= " } else {\n"; 67 ret ~= " die();\n"; 68 ret ~= " }\n"; 69 ret ~= " }\n"; 70 ret ~= " }\n"; 71 ret ~= " });\n"; 72 } 73 74 ret ~= " }\n"; 75 return ret; 76 }