Skip to content

Commit 7525719

Browse files
committed
add PreFireSessionResolvedEvent so app can inject logic before any SessionManager.Listener get called after session resolved
1 parent f85f8f7 commit 7525719

5 files changed

Lines changed: 107 additions & 150 deletions

File tree

src/main/java/act/app/ActionContext.java

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import act.data.MapUtil;
66
import act.data.RequestBodyParser;
77
import act.event.ActEvent;
8+
import act.event.EventBus;
89
import act.handler.RequestHandler;
910
import act.route.Router;
1011
import act.util.ActContext;
@@ -478,8 +479,10 @@ public void resolve() {
478479
resolveSession();
479480
resolveFlash();
480481
state = State.SESSION_RESOLVED;
482+
EventBus eventBus = app().eventBus();
483+
eventBus.emit(new PreFireSessionResolvedEvent(session, this));
481484
Act.sessionManager().fireSessionResolved(this);
482-
app().eventBus().emit(new SessionResolvedEvent(this));
485+
eventBus.emit(new SessionResolvedEvent(session, this));
483486
}
484487

485488
/**
@@ -695,15 +698,47 @@ public enum State {
695698
DESTROYED
696699
}
697700

698-
private static class ActionContextEvent extends ActEvent<ActionContext> {
701+
public static class ActionContextEvent extends ActEvent<ActionContext> {
699702
public ActionContextEvent(ActionContext source) {
700703
super(source);
701704
}
705+
706+
public ActionContext context() {
707+
return source();
708+
}
702709
}
703710

704-
public static class SessionResolvedEvent extends ActionContextEvent {
705-
public SessionResolvedEvent(ActionContext source) {
711+
private static class SessionEvent extends ActionContextEvent {
712+
private H.Session session;
713+
public SessionEvent(H.Session session, ActionContext source) {
706714
super(source);
715+
this.session = session;
716+
}
717+
718+
public H.Session session() {
719+
return session;
720+
}
721+
}
722+
723+
/**
724+
* This event is fired after session resolved and before any
725+
* {@link act.util.SessionManager.Listener} get called
726+
*/
727+
public static class PreFireSessionResolvedEvent extends SessionEvent {
728+
public PreFireSessionResolvedEvent(H.Session session, ActionContext context) {
729+
super(session, context);
730+
}
731+
}
732+
733+
/**
734+
* This event is fired after session resolved and after all
735+
* {@link act.util.SessionManager.Listener} get notified and
736+
* in turn after all event listeners that listen to the
737+
* {@link PreFireSessionResolvedEvent} get notified
738+
*/
739+
public static class SessionResolvedEvent extends SessionEvent {
740+
public SessionResolvedEvent(H.Session session, ActionContext context) {
741+
super(session, context);
707742
}
708743
}
709744

src/main/java/act/app/AppClassLoader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,10 @@ protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundE
156156
return c;
157157
}
158158

159+
if (name.contains("act.fsa.jobs.JobApp")) {
160+
$.nil();
161+
}
162+
159163
// ensure we
160164
if (name.startsWith("act.") && name.endsWith("Admin")) {
161165
return super.loadClass(name, resolve);

src/main/java/act/event/EventBus.java

Lines changed: 62 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import act.app.event.AppEventId;
99
import act.app.event.AppEventListener;
1010
import act.job.AppJobManager;
11+
import org.osgl.mvc.result.Result;
1112
import org.osgl.util.C;
1213
import org.osgl.util.E;
1314

@@ -122,34 +123,62 @@ public synchronized EventBus bindAsync(Class<? extends EventObject> c, ActEventL
122123
return _bind(asyncActEventListeners, c, l);
123124
}
124125

125-
public synchronized EventBus emit(AppEventId eventId) {
126-
return emit(appEventLookup.get(eventId));
127-
}
128126

129-
public synchronized EventBus emit(final AppEvent event) {
130-
List<AppEventListener> ll = asyncAppEventListeners[event.id()];
131-
final AppJobManager jobManager = app().jobManager();
132-
for (final AppEventListener l : ll) {
133-
jobManager.now(new Callable<Void>() {
134-
@Override
135-
public Void call() throws Exception {
136-
l.on(event);
137-
return null;
138-
}
139-
});
127+
@SuppressWarnings("unchecked")
128+
private void callOn(ActEvent e, ActEventListener l) {
129+
try {
130+
l.on(e);
131+
} catch (Result r) {
132+
// in case event listener needs to return a result back
133+
throw r;
134+
} catch (Exception x) {
135+
logger.error(x, "Error executing job");
140136
}
141-
ll.clear();
137+
}
142138

143-
ll = appEventListeners[event.id()];
144-
for (AppEventListener l : ll) {
145-
try {
146-
l.on(event);
147-
} catch (Exception e) {
148-
logger.error(e, "Error executing job");
149-
throw E.tbd("support handling exception in jobs");
139+
private <T extends ActEvent> void callOn(final T event, List<? extends ActEventListener> listeners, boolean async) {
140+
if (null == listeners) {
141+
return;
142+
}
143+
AppJobManager jobManager = null;
144+
if (async) {
145+
jobManager = app().jobManager();
146+
}
147+
// copy the list to avoid ConcurrentModificationException
148+
listeners = C.list(listeners);
149+
for (final ActEventListener l : listeners) {
150+
if (!async) {
151+
callOn(event, l);
152+
} else {
153+
jobManager.now(new Callable<Object>() {
154+
@Override
155+
public Object call() throws Exception {
156+
callOn(event, l);
157+
return null;
158+
}
159+
});
150160
}
151161
}
152-
ll.clear();
162+
}
163+
164+
@SuppressWarnings("unchecked")
165+
private void callOn(final AppEvent event, List[] appEventListeners, boolean async) {
166+
List<AppEventListener> ll = appEventListeners[event.id()];
167+
callOn(event, ll, async);
168+
}
169+
170+
private void callOn(ActEvent event, Map<Class<? extends EventObject>, List<ActEventListener>> listeners, boolean async) {
171+
List<ActEventListener> list = listeners.get(event.eventType());
172+
callOn(event, list, async);
173+
}
174+
175+
public synchronized EventBus emit(AppEventId eventId) {
176+
return emit(appEventLookup.get(eventId));
177+
}
178+
179+
public synchronized EventBus emit(final AppEvent event) {
180+
callOn(event, asyncAppEventListeners, true);
181+
callOn(event, appEventListeners, false);
153182
return this;
154183
}
155184

@@ -158,27 +187,8 @@ public synchronized EventBus emitAsync(AppEventId eventId) {
158187
}
159188

160189
public synchronized EventBus emitAsync(final AppEvent event) {
161-
List<AppEventListener> ll = asyncAppEventListeners[event.id()];
162-
AppJobManager jobManager = app().jobManager();
163-
for (final AppEventListener l : ll) {
164-
jobManager.now(new Callable<Void>() {
165-
@Override
166-
public Void call() throws Exception {
167-
l.on(event);
168-
return null;
169-
}
170-
});
171-
}
172-
ll = appEventListeners[event.id()];
173-
for (final AppEventListener l : ll) {
174-
jobManager.now(new Callable<Void>() {
175-
@Override
176-
public Void call() throws Exception {
177-
l.on(event);
178-
return null;
179-
}
180-
});
181-
}
190+
callOn(event, asyncAppEventListeners, true);
191+
callOn(event, appEventListeners, true);
182192
return this;
183193
}
184194

@@ -187,118 +197,27 @@ public synchronized EventBus emitSync(AppEventId eventId) {
187197
}
188198

189199
public synchronized EventBus emitSync(AppEvent event) {
190-
List<AppEventListener> ll = asyncAppEventListeners[event.id()];
191-
for (AppEventListener l : ll) {
192-
try {
193-
l.on(event);
194-
} catch (Exception e) {
195-
logger.error(e, "Error executing job");
196-
throw E.tbd("Support exception in jobs");
197-
}
198-
}
199-
ll = appEventListeners[event.id()];
200-
for (AppEventListener l : ll) {
201-
try {
202-
l.on(event);
203-
} catch (Exception e) {
204-
logger.error(e, "Error executing job");
205-
throw E.tbd("Support exception in jobs");
206-
}
207-
}
200+
callOn(event, asyncAppEventListeners, false);
201+
callOn(event, appEventListeners, false);
208202
return this;
209203
}
210204

211205
public synchronized EventBus emitSync(final ActEvent event) {
212-
Class<? extends ActEvent> c = event.getClass();
213-
while (c.getName().contains("$")) {
214-
c = (Class) c.getSuperclass();
215-
}
216-
List<ActEventListener> list = asyncActEventListeners.get(c);
217-
AppJobManager jobManager = app().jobManager();
218-
if (null != list) {
219-
for (final ActEventListener l : list) {
220-
try {
221-
l.on(event);
222-
} catch (Exception e) {
223-
logger.error(e, "Error executing job");
224-
throw E.tbd("Support exception in jobs");
225-
}
226-
}
227-
}
228-
list = actEventListeners.get(c);
229-
if (null != list) {
230-
for (ActEventListener l : list) {
231-
try {
232-
l.on(event);
233-
} catch (Exception e) {
234-
logger.error(e, "Error executing job");
235-
throw E.tbd("Support exception in jobs");
236-
}
237-
}
238-
}
206+
callOn(event, asyncActEventListeners, false);
207+
callOn(event, actEventListeners, false);
239208
return this;
240209
}
241210

242211
@SuppressWarnings("unchecked")
243212
public synchronized EventBus emit(final ActEvent event) {
244-
Class<? extends ActEvent> c = event.eventType();
245-
List<ActEventListener> list = asyncActEventListeners.get(c);
246-
AppJobManager jobManager = app().jobManager();
247-
if (null != list) {
248-
for (final ActEventListener l : list) {
249-
jobManager.now(new Callable<Void>() {
250-
@Override
251-
public Void call() throws Exception {
252-
l.on(event);
253-
return null;
254-
}
255-
});
256-
}
257-
}
258-
list = actEventListeners.get(c);
259-
if (null != list) {
260-
for (ActEventListener l : list) {
261-
try {
262-
l.on(event);
263-
} catch (Exception e) {
264-
logger.error(e, "Error executing job");
265-
throw E.tbd("Support exception in jobs");
266-
}
267-
}
268-
}
213+
callOn(event, asyncActEventListeners, true);
214+
callOn(event, actEventListeners, false);
269215
return this;
270216
}
271217

272218
public synchronized EventBus emitAsync(final ActEvent event) {
273-
Class<? extends ActEvent> c = event.getClass();
274-
while (c.getName().contains("$")) {
275-
c = (Class) c.getSuperclass();
276-
}
277-
List<ActEventListener> list = asyncActEventListeners.get(c);
278-
AppJobManager jobManager = app().jobManager();
279-
if (null != list) {
280-
for (final ActEventListener l : list) {
281-
jobManager.now(new Callable<Void>() {
282-
@Override
283-
public Void call() throws Exception {
284-
l.on(event);
285-
return null;
286-
}
287-
});
288-
}
289-
}
290-
list = actEventListeners.get(c);
291-
if (null != list) {
292-
for (final ActEventListener l : list) {
293-
jobManager.now(new Callable<Void>() {
294-
@Override
295-
public Void call() throws Exception {
296-
l.on(event);
297-
return null;
298-
}
299-
});
300-
}
301-
}
219+
callOn(event, asyncActEventListeners, true);
220+
callOn(event, actEventListeners, true);
302221
return this;
303222
}
304223

src/main/java/act/util/AppCodeScannerPluginBase.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import org.osgl.logging.Logger;
1111

1212
@ActComponent
13-
public abstract class AppCodeScannerPluginBase implements Plugin {
13+
public abstract class AppCodeScannerPluginBase extends DestroyableBase implements Plugin {
1414

1515
protected final static Logger logger = L.get(AppCodeScannerPluginBase.class);
1616

src/main/java/act/util/SessionManager.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ private CookieResolver getResolver(ActionContext context) {
104104
}
105105
}
106106

107-
@ActComponent
108-
public static class Listener extends DestroyableBase implements Plugin {
107+
public static abstract class Listener extends DestroyableBase implements Plugin {
109108
@Override
110109
public void register() {
111110
Act.sessionManager().register(this);

0 commit comments

Comments
 (0)