Merge lp:~mmcm/akiban-server/script-invoker-pool into lp:~akiban-technologies/akiban-server/trunk
- script-invoker-pool
- Merge into trunk
Proposed by
Mike McMahon
Status: | Merged |
---|---|
Approved by: | Nathan Williams |
Approved revision: | 2620 |
Merged at revision: | 2620 |
Proposed branch: | lp:~mmcm/akiban-server/script-invoker-pool |
Merge into: | lp:~akiban-technologies/akiban-server/trunk |
Diff against target: |
460 lines (+171/-79) 8 files modified
src/main/java/com/akiban/server/service/restdml/DirectServiceImpl.java (+23/-6) src/main/java/com/akiban/server/service/routines/RoutineLoader.java (+1/-0) src/main/java/com/akiban/server/service/routines/RoutineLoaderImpl.java (+5/-0) src/main/java/com/akiban/server/service/routines/ScriptCache.java (+107/-68) src/main/java/com/akiban/server/service/routines/ScriptInvoker.java (+1/-3) src/main/java/com/akiban/server/service/routines/ScriptLibrary.java (+25/-0) src/main/java/com/akiban/sql/script/ScriptFunctionJavaRoutine.java (+4/-2) src/test/java/com/akiban/server/service/routines/MockRoutineLoader.java (+5/-0) |
To merge this branch: | bzr merge lp:~mmcm/akiban-server/script-invoker-pool |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Nathan Williams | Approve | ||
Review via email: mp+158507@code.launchpad.net |
Commit message
Description of the change
Clean up ScriptInvoker as mentioned in lp:~pbeaman/akiban-server/direct-param-handling/+merge/156711/comments/343411
Now distinguishes the invoker proper from the library from which it comes. There are still no cases where more than one routine comes from the same library (a functional calling convention has one and a direct module has zero), but the pool itself now supports it, pooling the big ScriptEngine/
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/main/java/com/akiban/server/service/restdml/DirectServiceImpl.java' | |||
2 | --- src/main/java/com/akiban/server/service/restdml/DirectServiceImpl.java 2013-04-11 00:14:28 +0000 | |||
3 | +++ src/main/java/com/akiban/server/service/restdml/DirectServiceImpl.java 2013-04-11 23:35:24 +0000 | |||
4 | @@ -62,7 +62,8 @@ | |||
5 | 62 | import com.akiban.server.service.restdml.EndpointMetadata.ParamMetadata; | 62 | import com.akiban.server.service.restdml.EndpointMetadata.ParamMetadata; |
6 | 63 | import com.akiban.server.service.restdml.EndpointMetadata.Tokenizer; | 63 | import com.akiban.server.service.restdml.EndpointMetadata.Tokenizer; |
7 | 64 | import com.akiban.server.service.routines.RoutineLoader; | 64 | import com.akiban.server.service.routines.RoutineLoader; |
9 | 65 | import com.akiban.server.service.routines.ScriptInvoker; | 65 | import com.akiban.server.service.routines.ScriptLibrary; |
10 | 66 | import com.akiban.server.service.routines.ScriptPool; | ||
11 | 66 | import com.akiban.server.service.security.SecurityService; | 67 | import com.akiban.server.service.security.SecurityService; |
12 | 67 | import com.akiban.server.service.session.Session; | 68 | import com.akiban.server.service.session.Session; |
13 | 68 | import com.akiban.server.types3.Attribute; | 69 | import com.akiban.server.types3.Attribute; |
14 | @@ -394,9 +395,19 @@ | |||
15 | 394 | 395 | ||
16 | 395 | final Object[] args = createArgsArray(pathParams, queryParameters, content, cache, md); | 396 | final Object[] args = createArgsArray(pathParams, queryParameters, content, cache, md); |
17 | 396 | 397 | ||
21 | 397 | final ScriptInvoker invoker = conn.getRoutineLoader() | 398 | final ScriptPool<ScriptLibrary> libraryPool = conn.getRoutineLoader() |
22 | 398 | .getScriptInvoker(conn.getSession(), new TableName(procName.getSchemaName(), md.routineName)).get(); | 399 | .getScriptLibrary(conn.getSession(), new TableName(procName.getSchemaName(), |
23 | 399 | Object result = invoker.invokeNamedFunction(md.function, args); | 400 | md.routineName)); |
24 | 401 | final ScriptLibrary library = libraryPool.get(); | ||
25 | 402 | boolean success = false; | ||
26 | 403 | Object result; | ||
27 | 404 | try { | ||
28 | 405 | result = library.invoke(md.function, args); | ||
29 | 406 | success = true; | ||
30 | 407 | } | ||
31 | 408 | finally { | ||
32 | 409 | libraryPool.put(library, success); | ||
33 | 410 | } | ||
34 | 400 | 411 | ||
35 | 401 | switch (md.outParam.type) { | 412 | switch (md.outParam.type) { |
36 | 402 | 413 | ||
37 | @@ -529,9 +540,11 @@ | |||
38 | 529 | for (final Routine routine : ais.getRoutines().values()) { | 540 | for (final Routine routine : ais.getRoutines().values()) { |
39 | 530 | if (routine.getCallingConvention().equals(CallingConvention.SCRIPT_LIBRARY) | 541 | if (routine.getCallingConvention().equals(CallingConvention.SCRIPT_LIBRARY) |
40 | 531 | && routine.getDynamicResultSets() == 0 && routine.getParameters().isEmpty()) { | 542 | && routine.getDynamicResultSets() == 0 && routine.getParameters().isEmpty()) { |
41 | 543 | final ScriptPool<ScriptLibrary> libraryPool = routineLoader.getScriptLibrary(session, routine.getName()); | ||
42 | 544 | final ScriptLibrary library = libraryPool.get(); | ||
43 | 545 | boolean success = false; | ||
44 | 532 | try { | 546 | try { |
47 | 533 | final ScriptInvoker invoker = routineLoader.getScriptInvoker(session, routine.getName()).get(); | 547 | library.invoke(DISTINGUISHED_REGISTRATION_METHOD_NAME, |
46 | 534 | invoker.invokeNamedFunction(DISTINGUISHED_REGISTRATION_METHOD_NAME, | ||
48 | 535 | new Object[] { new RestFunctionRegistrar() { | 548 | new Object[] { new RestFunctionRegistrar() { |
49 | 536 | @Override | 549 | @Override |
50 | 537 | public void register(String specification) throws Exception { | 550 | public void register(String specification) throws Exception { |
51 | @@ -539,9 +552,11 @@ | |||
52 | 539 | .getTableName(), specification); | 552 | .getTableName(), specification); |
53 | 540 | } | 553 | } |
54 | 541 | } }); | 554 | } }); |
55 | 555 | success = true; | ||
56 | 542 | } catch (ExternalRoutineInvocationException e) { | 556 | } catch (ExternalRoutineInvocationException e) { |
57 | 543 | if (e.getCause() instanceof NoSuchMethodException) { | 557 | if (e.getCause() instanceof NoSuchMethodException) { |
58 | 544 | LOG.warn("Script library " + routine.getName() + " has no _register function"); | 558 | LOG.warn("Script library " + routine.getName() + " has no _register function"); |
59 | 559 | success = true; | ||
60 | 545 | return; | 560 | return; |
61 | 546 | } | 561 | } |
62 | 547 | Throwable previous = e; | 562 | Throwable previous = e; |
63 | @@ -557,6 +572,8 @@ | |||
64 | 557 | throw e; | 572 | throw e; |
65 | 558 | } catch (Exception e) { | 573 | } catch (Exception e) { |
66 | 559 | throw new RegistrationException(e); | 574 | throw new RegistrationException(e); |
67 | 575 | } finally { | ||
68 | 576 | libraryPool.put(library, success); | ||
69 | 560 | } | 577 | } |
70 | 561 | } | 578 | } |
71 | 562 | } | 579 | } |
72 | 563 | 580 | ||
73 | === modified file 'src/main/java/com/akiban/server/service/routines/RoutineLoader.java' | |||
74 | --- src/main/java/com/akiban/server/service/routines/RoutineLoader.java 2013-03-22 20:05:57 +0000 | |||
75 | +++ src/main/java/com/akiban/server/service/routines/RoutineLoader.java 2013-04-11 23:35:24 +0000 | |||
76 | @@ -33,5 +33,6 @@ | |||
77 | 33 | public boolean isScriptLanguage(Session session, String language); | 33 | public boolean isScriptLanguage(Session session, String language); |
78 | 34 | public ScriptPool<ScriptEvaluator> getScriptEvaluator(Session session, TableName routineName); | 34 | public ScriptPool<ScriptEvaluator> getScriptEvaluator(Session session, TableName routineName); |
79 | 35 | public ScriptPool<ScriptInvoker> getScriptInvoker(Session session, TableName routineName); | 35 | public ScriptPool<ScriptInvoker> getScriptInvoker(Session session, TableName routineName); |
80 | 36 | public ScriptPool<ScriptLibrary> getScriptLibrary(Session session, TableName routineName); | ||
81 | 36 | public void unloadRoutine(Session session, TableName routineName); | 37 | public void unloadRoutine(Session session, TableName routineName); |
82 | 37 | } | 38 | } |
83 | 38 | 39 | ||
84 | === modified file 'src/main/java/com/akiban/server/service/routines/RoutineLoaderImpl.java' | |||
85 | --- src/main/java/com/akiban/server/service/routines/RoutineLoaderImpl.java 2013-03-22 20:05:57 +0000 | |||
86 | +++ src/main/java/com/akiban/server/service/routines/RoutineLoaderImpl.java 2013-04-11 23:35:24 +0000 | |||
87 | @@ -194,6 +194,11 @@ | |||
88 | 194 | } | 194 | } |
89 | 195 | 195 | ||
90 | 196 | @Override | 196 | @Override |
91 | 197 | public ScriptPool<ScriptLibrary> getScriptLibrary(Session session, TableName routineName) { | ||
92 | 198 | return scripts.getScriptLibrary(session, routineName); | ||
93 | 199 | } | ||
94 | 200 | |||
95 | 201 | @Override | ||
96 | 197 | public void unloadRoutine(Session session, TableName routineName) { | 202 | public void unloadRoutine(Session session, TableName routineName) { |
97 | 198 | synchronized (loadablePlans) { | 203 | synchronized (loadablePlans) { |
98 | 199 | loadablePlans.remove(routineName); | 204 | loadablePlans.remove(routineName); |
99 | 200 | 205 | ||
100 | === modified file 'src/main/java/com/akiban/server/service/routines/ScriptCache.java' | |||
101 | --- src/main/java/com/akiban/server/service/routines/ScriptCache.java 2013-04-03 13:41:34 +0000 | |||
102 | +++ src/main/java/com/akiban/server/service/routines/ScriptCache.java 2013-04-11 23:35:24 +0000 | |||
103 | @@ -61,8 +61,12 @@ | |||
104 | 61 | return getEntry(session, routineName).getScriptEvaluator(); | 61 | return getEntry(session, routineName).getScriptEvaluator(); |
105 | 62 | } | 62 | } |
106 | 63 | 63 | ||
107 | 64 | public ScriptPool<ScriptLibrary> getScriptLibrary(Session session, TableName routineName) { | ||
108 | 65 | return getEntry(session, routineName).getScriptLibrary(); | ||
109 | 66 | } | ||
110 | 67 | |||
111 | 64 | public ScriptPool<ScriptInvoker> getScriptInvoker(Session session, TableName routineName) { | 68 | public ScriptPool<ScriptInvoker> getScriptInvoker(Session session, TableName routineName) { |
113 | 65 | return getEntry(session, routineName).getScriptInvoker(); | 69 | return getEntry(session, routineName).getScriptInvoker(this, session); |
114 | 66 | } | 70 | } |
115 | 67 | 71 | ||
116 | 68 | protected ScriptEngineManager getManager(Session session) { | 72 | protected ScriptEngineManager getManager(Session session) { |
117 | @@ -85,23 +89,25 @@ | |||
118 | 85 | return entry; | 89 | return entry; |
119 | 86 | } | 90 | } |
120 | 87 | 91 | ||
122 | 88 | static class CacheEntry { | 92 | class CacheEntry { |
123 | 89 | private TableName routineName; | 93 | private TableName routineName; |
124 | 90 | private String script; | 94 | private String script; |
125 | 95 | private TableName libraryName; | ||
126 | 91 | private String function; | 96 | private String function; |
127 | 92 | private ScriptEngineFactory factory; | 97 | private ScriptEngineFactory factory; |
128 | 93 | private String threading; | 98 | private String threading; |
129 | 94 | private boolean invocable, compilable; | 99 | private boolean invocable, compilable; |
130 | 95 | private ScriptPool<ScriptEvaluator> sharedEvaluatorPool; | 100 | private ScriptPool<ScriptEvaluator> sharedEvaluatorPool; |
132 | 96 | private ScriptPool<ScriptInvoker> sharedInvokerPool; | 101 | private ScriptPool<ScriptLibrary> sharedLibraryPool; |
133 | 97 | private ScriptEngine spareEngine; | 102 | private ScriptEngine spareEngine; |
134 | 98 | 103 | ||
135 | 99 | public CacheEntry(Routine routine, ScriptEngine engine) { | 104 | public CacheEntry(Routine routine, ScriptEngine engine) { |
136 | 100 | routineName = routine.getName(); | 105 | routineName = routine.getName(); |
137 | 101 | script = routine.getDefinition(); | 106 | script = routine.getDefinition(); |
138 | 107 | libraryName = routineName; // TODO: Until qualified EXTERNAL NAME supported. | ||
139 | 102 | function = routine.getMethodName(); | 108 | function = routine.getMethodName(); |
140 | 103 | factory = engine.getFactory(); | 109 | factory = engine.getFactory(); |
142 | 104 | threading = (String) factory.getParameter("THREADING"); | 110 | threading = (String)factory.getParameter("THREADING"); |
143 | 105 | invocable = (engine instanceof Invocable); | 111 | invocable = (engine instanceof Invocable); |
144 | 106 | compilable = (engine instanceof Compilable); | 112 | compilable = (engine instanceof Compilable); |
145 | 107 | spareEngine = engine; | 113 | spareEngine = engine; |
146 | @@ -127,9 +133,8 @@ | |||
147 | 127 | } | 133 | } |
148 | 128 | } | 134 | } |
149 | 129 | 135 | ||
153 | 130 | // Otherwise, every caller gets a new pool which only has the scope | 136 | // Otherwise, every caller gets a new pool which only has |
154 | 131 | // of the | 137 | // the scope of the prepared statement, etc. |
152 | 132 | // prepared statement, etc. | ||
155 | 133 | ScriptEngine engine; | 138 | ScriptEngine engine; |
156 | 134 | synchronized (this) { | 139 | synchronized (this) { |
157 | 135 | engine = spareEngine; | 140 | engine = spareEngine; |
158 | @@ -149,42 +154,54 @@ | |||
159 | 149 | } | 154 | } |
160 | 150 | } | 155 | } |
161 | 151 | 156 | ||
171 | 152 | public ScriptPool<ScriptInvoker> getScriptInvoker() { | 157 | public ScriptPool<ScriptLibrary> getScriptLibrary() { |
172 | 153 | // TODO - talk with Mike about having a CacheEntry without a function - | 158 | assert invocable; |
173 | 154 | // needed for the LIBRARY param styl | 159 | // Can share if at multi-threaded (or stronger), since we |
174 | 155 | assert invocable ; //&& (function != null); | 160 | // are invoking the function. |
175 | 156 | // Can share if at multi-threaded (or stronger), since we are | 161 | if ("MULTITHREADED".equals(threading) || |
176 | 157 | // invoking | 162 | "THREAD-ISOLATED".equals(threading) || |
177 | 158 | // the function. | 163 | "STATELESS".equals(threading)) { |
169 | 159 | if ("MULTITHREADED".equals(threading) || "THREAD-ISOLATED".equals(threading) | ||
170 | 160 | || "STATELESS".equals(threading)) { | ||
178 | 161 | synchronized (this) { | 164 | synchronized (this) { |
180 | 162 | if (sharedInvokerPool == null) { | 165 | if (sharedLibraryPool == null) { |
181 | 163 | ScriptEngine engine = spareEngine; | 166 | ScriptEngine engine = spareEngine; |
182 | 164 | if (engine != null) | 167 | if (engine != null) |
183 | 165 | spareEngine = null; | 168 | spareEngine = null; |
184 | 166 | else | 169 | else |
185 | 167 | engine = factory.getScriptEngine(); | 170 | engine = factory.getScriptEngine(); |
188 | 168 | ScriptInvoker invoker = new Invoker(routineName, engine, script, function); | 171 | ScriptLibrary library = new Library(routineName, engine, script); |
189 | 169 | sharedInvokerPool = new SharedPool<>(invoker); | 172 | sharedLibraryPool = new SharedPool<>(library); |
190 | 170 | } | 173 | } |
192 | 171 | return sharedInvokerPool; | 174 | return sharedLibraryPool; |
193 | 172 | } | 175 | } |
194 | 173 | } | 176 | } |
195 | 174 | 177 | ||
199 | 175 | // Otherwise, every caller gets a new pool which only has the scope | 178 | // Otherwise, every caller gets a new pool which only has |
200 | 176 | // of the | 179 | // the scope of the prepared statement, etc. |
198 | 177 | // prepared statement, etc. | ||
201 | 178 | ScriptEngine engine; | 180 | ScriptEngine engine; |
202 | 179 | synchronized (this) { | 181 | synchronized (this) { |
203 | 180 | engine = spareEngine; | 182 | engine = spareEngine; |
204 | 181 | if (engine != null) | 183 | if (engine != null) |
205 | 182 | spareEngine = null; | 184 | spareEngine = null; |
206 | 183 | } | 185 | } |
208 | 184 | Invoker invoker = null; | 186 | Library library = null; |
209 | 185 | if (engine != null) | 187 | if (engine != null) |
212 | 186 | invoker = new Invoker(routineName, engine, script, function); | 188 | library = new Library(routineName, engine, script); |
213 | 187 | return new InvokerPool(routineName, factory, script, function, invoker); | 189 | return new LibraryPool(routineName, factory, script, library); |
214 | 190 | } | ||
215 | 191 | |||
216 | 192 | public ScriptPool<ScriptInvoker> getScriptInvoker(ScriptCache cache, Session session) { | ||
217 | 193 | assert invocable && (function != null); | ||
218 | 194 | ScriptPool<ScriptLibrary> libraryPool; | ||
219 | 195 | if (routineName.equals(libraryName)) { | ||
220 | 196 | libraryPool = getScriptLibrary(); | ||
221 | 197 | } | ||
222 | 198 | else { | ||
223 | 199 | synchronized (this) { | ||
224 | 200 | spareEngine = null; | ||
225 | 201 | } | ||
226 | 202 | libraryPool = cache.getScriptLibrary(session, libraryName); | ||
227 | 203 | } | ||
228 | 204 | return new InvokerPool(libraryPool, function); | ||
229 | 188 | } | 205 | } |
230 | 189 | } | 206 | } |
231 | 190 | 207 | ||
232 | @@ -277,18 +294,14 @@ | |||
233 | 277 | } | 294 | } |
234 | 278 | } | 295 | } |
235 | 279 | 296 | ||
241 | 280 | static class InvokerPool extends BasePool<ScriptInvoker> { | 297 | static class LibraryPool extends BasePool<ScriptLibrary> { |
242 | 281 | private final String function; | 298 | public LibraryPool(TableName routineName, ScriptEngineFactory factory, String script, Library initial) { |
238 | 282 | |||
239 | 283 | public InvokerPool(TableName routineName, ScriptEngineFactory factory, String script, String function, | ||
240 | 284 | Invoker initial) { | ||
243 | 285 | super(routineName, factory, script, initial); | 299 | super(routineName, factory, script, initial); |
244 | 286 | this.function = function; | ||
245 | 287 | } | 300 | } |
246 | 288 | 301 | ||
247 | 289 | @Override | 302 | @Override |
250 | 290 | protected Invoker create() { | 303 | protected Library create() { |
251 | 291 | return new Invoker(routineName, factory.getScriptEngine(), script, function); | 304 | return new Library(routineName, factory.getScriptEngine(), script); |
252 | 292 | } | 305 | } |
253 | 293 | } | 306 | } |
254 | 294 | 307 | ||
255 | @@ -396,14 +409,12 @@ | |||
256 | 396 | } | 409 | } |
257 | 397 | } | 410 | } |
258 | 398 | 411 | ||
260 | 399 | static class Invoker implements ScriptInvoker { | 412 | static class Library implements ScriptLibrary { |
261 | 400 | private final TableName routineName; | 413 | private final TableName routineName; |
262 | 401 | private final String function; | ||
263 | 402 | private final Invocable invocable; | 414 | private final Invocable invocable; |
264 | 403 | 415 | ||
266 | 404 | public Invoker(TableName routineName, ScriptEngine engine, String script, String function) { | 416 | public Library(TableName routineName, ScriptEngine engine, String script) { |
267 | 405 | this.routineName = routineName; | 417 | this.routineName = routineName; |
268 | 406 | this.function = function; | ||
269 | 407 | setScriptName(routineName, engine); | 418 | setScriptName(routineName, engine); |
270 | 408 | try { | 419 | try { |
271 | 409 | if (engine instanceof Compilable) { | 420 | if (engine instanceof Compilable) { |
272 | @@ -420,42 +431,70 @@ | |||
273 | 420 | } | 431 | } |
274 | 421 | 432 | ||
275 | 422 | @Override | 433 | @Override |
276 | 434 | public String getEngineName() { | ||
277 | 435 | return ((ScriptEngine) invocable).getFactory().getEngineName(); | ||
278 | 436 | } | ||
279 | 437 | |||
280 | 438 | @Override | ||
281 | 439 | public boolean isCompiled() { | ||
282 | 440 | return (invocable instanceof Compilable); | ||
283 | 441 | } | ||
284 | 442 | |||
285 | 443 | @Override | ||
286 | 444 | public Object invoke(String function, Object[] args) { | ||
287 | 445 | logger.debug("Calling {} in {}", function, routineName); | ||
288 | 446 | try { | ||
289 | 447 | return invocable.invokeFunction(function, args); | ||
290 | 448 | } catch (ScriptException ex) { | ||
291 | 449 | throw new ExternalRoutineInvocationException(routineName, ex); | ||
292 | 450 | } catch (NoSuchMethodException ex) { | ||
293 | 451 | throw new ExternalRoutineInvocationException(routineName, ex); | ||
294 | 452 | } | ||
295 | 453 | } | ||
296 | 454 | } | ||
297 | 455 | |||
298 | 456 | static class InvokerPool implements ScriptPool<ScriptInvoker> { | ||
299 | 457 | private final ScriptPool<ScriptLibrary> libraryPool; | ||
300 | 458 | private final String function; | ||
301 | 459 | |||
302 | 460 | public InvokerPool(ScriptPool<ScriptLibrary> libraryPool, String function) { | ||
303 | 461 | this.libraryPool = libraryPool; | ||
304 | 462 | this.function = function; | ||
305 | 463 | } | ||
306 | 464 | |||
307 | 465 | @Override | ||
308 | 466 | public ScriptInvoker get() { | ||
309 | 467 | return new Invoker(libraryPool.get(), function); | ||
310 | 468 | } | ||
311 | 469 | |||
312 | 470 | @Override | ||
313 | 471 | public void put(ScriptInvoker elem, boolean success) { | ||
314 | 472 | libraryPool.put(elem.getLibrary(), success); | ||
315 | 473 | } | ||
316 | 474 | } | ||
317 | 475 | |||
318 | 476 | static class Invoker implements ScriptInvoker { | ||
319 | 477 | private final ScriptLibrary library; | ||
320 | 478 | private final String function; | ||
321 | 479 | |||
322 | 480 | public Invoker(ScriptLibrary library, String function) { | ||
323 | 481 | this.library = library; | ||
324 | 482 | this.function = function; | ||
325 | 483 | } | ||
326 | 484 | |||
327 | 485 | @Override | ||
328 | 486 | public ScriptLibrary getLibrary() { | ||
329 | 487 | return library; | ||
330 | 488 | } | ||
331 | 489 | |||
332 | 490 | @Override | ||
333 | 423 | public String getFunctionName() { | 491 | public String getFunctionName() { |
334 | 424 | return function; | 492 | return function; |
335 | 425 | } | 493 | } |
336 | 426 | 494 | ||
337 | 427 | @Override | 495 | @Override |
338 | 428 | public String getEngineName() { | ||
339 | 429 | return ((ScriptEngine) invocable).getFactory().getEngineName(); | ||
340 | 430 | } | ||
341 | 431 | |||
342 | 432 | @Override | ||
343 | 433 | public boolean isCompiled() { | ||
344 | 434 | return (invocable instanceof Compilable); | ||
345 | 435 | } | ||
346 | 436 | |||
347 | 437 | @Override | ||
348 | 438 | public Object invoke(Object[] args) { | 496 | public Object invoke(Object[] args) { |
369 | 439 | logger.debug("Calling {} in {}", function, routineName); | 497 | return library.invoke(function, args); |
350 | 440 | try { | ||
351 | 441 | return invocable.invokeFunction(function, args); | ||
352 | 442 | } catch (ScriptException ex) { | ||
353 | 443 | throw new ExternalRoutineInvocationException(routineName, ex); | ||
354 | 444 | } catch (NoSuchMethodException ex) { | ||
355 | 445 | throw new ExternalRoutineInvocationException(routineName, ex); | ||
356 | 446 | } | ||
357 | 447 | } | ||
358 | 448 | |||
359 | 449 | @Override | ||
360 | 450 | public Object invokeNamedFunction(String functionName, Object[] args) { | ||
361 | 451 | logger.debug("Calling {} in {}", function, routineName); | ||
362 | 452 | try { | ||
363 | 453 | return invocable.invokeFunction(functionName, args); | ||
364 | 454 | } catch (ScriptException ex) { | ||
365 | 455 | throw new ExternalRoutineInvocationException(routineName, ex); | ||
366 | 456 | } catch (NoSuchMethodException ex) { | ||
367 | 457 | throw new ExternalRoutineInvocationException(routineName, ex); | ||
368 | 458 | } | ||
370 | 459 | } | 498 | } |
371 | 460 | } | 499 | } |
372 | 461 | } | 500 | } |
373 | 462 | 501 | ||
374 | === modified file 'src/main/java/com/akiban/server/service/routines/ScriptInvoker.java' | |||
375 | --- src/main/java/com/akiban/server/service/routines/ScriptInvoker.java 2013-03-28 21:05:55 +0000 | |||
376 | +++ src/main/java/com/akiban/server/service/routines/ScriptInvoker.java 2013-04-11 23:35:24 +0000 | |||
377 | @@ -19,9 +19,7 @@ | |||
378 | 19 | 19 | ||
379 | 20 | public interface ScriptInvoker | 20 | public interface ScriptInvoker |
380 | 21 | { | 21 | { |
382 | 22 | public String getEngineName(); | 22 | public ScriptLibrary getLibrary(); |
383 | 23 | public String getFunctionName(); | 23 | public String getFunctionName(); |
384 | 24 | public boolean isCompiled(); | ||
385 | 25 | public Object invoke(Object[] args); | 24 | public Object invoke(Object[] args); |
386 | 26 | public Object invokeNamedFunction(String functionName, Object[] args); | ||
387 | 27 | } | 25 | } |
388 | 28 | 26 | ||
389 | === added file 'src/main/java/com/akiban/server/service/routines/ScriptLibrary.java' | |||
390 | --- src/main/java/com/akiban/server/service/routines/ScriptLibrary.java 1970-01-01 00:00:00 +0000 | |||
391 | +++ src/main/java/com/akiban/server/service/routines/ScriptLibrary.java 2013-04-11 23:35:24 +0000 | |||
392 | @@ -0,0 +1,25 @@ | |||
393 | 1 | /** | ||
394 | 2 | * Copyright (C) 2009-2013 Akiban Technologies, Inc. | ||
395 | 3 | * | ||
396 | 4 | * This program is free software: you can redistribute it and/or modify | ||
397 | 5 | * it under the terms of the GNU Affero General Public License as published by | ||
398 | 6 | * the Free Software Foundation, either version 3 of the License, or | ||
399 | 7 | * (at your option) any later version. | ||
400 | 8 | * | ||
401 | 9 | * This program is distributed in the hope that it will be useful, | ||
402 | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
403 | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
404 | 12 | * GNU Affero General Public License for more details. | ||
405 | 13 | * | ||
406 | 14 | * You should have received a copy of the GNU Affero General Public License | ||
407 | 15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
408 | 16 | */ | ||
409 | 17 | |||
410 | 18 | package com.akiban.server.service.routines; | ||
411 | 19 | |||
412 | 20 | public interface ScriptLibrary | ||
413 | 21 | { | ||
414 | 22 | public String getEngineName(); | ||
415 | 23 | public boolean isCompiled(); | ||
416 | 24 | public Object invoke(String function, Object[] args); | ||
417 | 25 | } | ||
418 | 0 | 26 | ||
419 | === modified file 'src/main/java/com/akiban/sql/script/ScriptFunctionJavaRoutine.java' | |||
420 | --- src/main/java/com/akiban/sql/script/ScriptFunctionJavaRoutine.java 2013-03-22 20:05:57 +0000 | |||
421 | +++ src/main/java/com/akiban/sql/script/ScriptFunctionJavaRoutine.java 2013-04-11 23:35:24 +0000 | |||
422 | @@ -32,6 +32,7 @@ | |||
423 | 32 | import com.akiban.server.explain.Label; | 32 | import com.akiban.server.explain.Label; |
424 | 33 | import com.akiban.server.explain.PrimitiveExplainer; | 33 | import com.akiban.server.explain.PrimitiveExplainer; |
425 | 34 | import com.akiban.server.service.routines.ScriptInvoker; | 34 | import com.akiban.server.service.routines.ScriptInvoker; |
426 | 35 | import com.akiban.server.service.routines.ScriptLibrary; | ||
427 | 35 | import com.akiban.server.service.routines.ScriptPool; | 36 | import com.akiban.server.service.routines.ScriptPool; |
428 | 36 | 37 | ||
429 | 37 | import java.sql.ResultSet; | 38 | import java.sql.ResultSet; |
430 | @@ -129,11 +130,12 @@ | |||
431 | 129 | public CompoundExplainer getExplainer(ExplainContext context) { | 130 | public CompoundExplainer getExplainer(ExplainContext context) { |
432 | 130 | Attributes atts = new Attributes(); | 131 | Attributes atts = new Attributes(); |
433 | 131 | ScriptInvoker invoker = pool.get(); | 132 | ScriptInvoker invoker = pool.get(); |
434 | 133 | ScriptLibrary library = invoker.getLibrary(); | ||
435 | 132 | atts.put(Label.PROCEDURE_IMPLEMENTATION, | 134 | atts.put(Label.PROCEDURE_IMPLEMENTATION, |
437 | 133 | PrimitiveExplainer.getInstance(invoker.getEngineName())); | 135 | PrimitiveExplainer.getInstance(library.getEngineName())); |
438 | 134 | atts.put(Label.PROCEDURE_IMPLEMENTATION, | 136 | atts.put(Label.PROCEDURE_IMPLEMENTATION, |
439 | 135 | PrimitiveExplainer.getInstance(invoker.getFunctionName())); | 137 | PrimitiveExplainer.getInstance(invoker.getFunctionName())); |
441 | 136 | if (invoker.isCompiled()) | 138 | if (library.isCompiled()) |
442 | 137 | atts.put(Label.PROCEDURE_IMPLEMENTATION, | 139 | atts.put(Label.PROCEDURE_IMPLEMENTATION, |
443 | 138 | PrimitiveExplainer.getInstance("compiled")); | 140 | PrimitiveExplainer.getInstance("compiled")); |
444 | 139 | pool.put(invoker, true); | 141 | pool.put(invoker, true); |
445 | 140 | 142 | ||
446 | === modified file 'src/test/java/com/akiban/server/service/routines/MockRoutineLoader.java' | |||
447 | --- src/test/java/com/akiban/server/service/routines/MockRoutineLoader.java 2013-03-22 20:05:57 +0000 | |||
448 | +++ src/test/java/com/akiban/server/service/routines/MockRoutineLoader.java 2013-04-11 23:35:24 +0000 | |||
449 | @@ -62,6 +62,11 @@ | |||
450 | 62 | } | 62 | } |
451 | 63 | 63 | ||
452 | 64 | @Override | 64 | @Override |
453 | 65 | public ScriptPool<ScriptLibrary> getScriptLibrary(Session session, TableName routineName) { | ||
454 | 66 | throw new UnsupportedOperationException(); | ||
455 | 67 | } | ||
456 | 68 | |||
457 | 69 | @Override | ||
458 | 65 | public void unloadRoutine(Session session, TableName routineName) { | 70 | public void unloadRoutine(Session session, TableName routineName) { |
459 | 66 | throw new UnsupportedOperationException(); | 71 | throw new UnsupportedOperationException(); |
460 | 67 | } | 72 | } |
Looks plausible.