| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- using Astralis;
- using Invercargill.DataStructures;
- using Inversion;
- namespace Spry {
- public class ContinuationProvider : SseEndpoint {
- private Dictionary<string, Component> components = new Dictionary<string, Component>();
- private Dictionary<string, bool> active_channels = new Dictionary<string, bool>();
- public override uint retry_interval { get { return 500; } }
- public async override void new_connection(HttpContext http_context, RouteContext route_context, SseStream stream) {
- var continuation_id = route_context.mapped_parameters.get_or_default("token");
- Component component = null;
- lock(active_channels) {
- if(components.try_get(continuation_id, out component)) {
- active_channels[continuation_id] = true;
- }
- }
- try {
- if(component == null) {
- yield stream.send_event(new SseEvent.with_type("_spry-close", "404"));
- }
- try {
- yield component.continuation(stream);
- }
- catch(Error e) {
- warning(@"Component $(component.get_type().name()) threw exception in follow up: $(e.message)");
- yield stream.send_event(new SseEvent.with_type("_spry-close", "500"));
- }
- yield stream.send_event(new SseEvent.with_type("_spry-close", "200"));
- }
- catch(Error e) {
- warning("Failed to send '_spry-close' event: " + e.message);
- return;
- }
- }
-
- public string get_continuation_path(Component component) {
- var id = Uuid.string_random();
- components[id] = component;
- active_channels[id] = false;
- // Remove component after 60 seconds if no connection has been made
- Timeout.add_seconds_once(60, () => clean(id));
- return @"/_spry/cnu/$id";
- }
- private void clean(string id) {
- bool active;
- lock(active_channels){
- if(!active_channels.try_get(id, out active)) {
- components.remove(id);
- return;
- }
- if(!active) {
- components.remove(id);
- active_channels.remove(id);
- }
- }
- }
- }
- }
|