[Freeswitch-users] Subscribing to events in managed C# / .NET

Josh Rivers josh at radianttiger.com
Wed Sep 23 15:59:44 PDT 2009


I've been having the same idea, except completely different. I'd probably
start with StructureMap or MEF. I'm attracted to the idea of creating an
alternative to mod_event_socket except using WCF as the transport, enabling
both WS-* and Rest access into the FreeSWITCH core.

I think an effort to create a better archtecture in mod_managed is likely to
get very religious very quickly. There's a _lot_ of difference of opinion in
the .NET ecosystem. Just witness Michael and I disagreeing on something as
simple as how to handle unhandled exceptions.

Instead of architecting a more complete solution, I think a good solution
might be to de-architect the current solution to easily enable extensibility
and component replacement. That way, each of us can have the high-level
framework we want without disagreement on the low-level framework. This is
the same model used in ASP.NET MVC, where it works well out of the box, but
you can easily hook in and replace any chunk of it you want if your needs
vary.

I started playing with a refactoring of the current managed.dll in order to
make it more pluggable. It kinda got away from me....<grin>....I've
published my code up on github at
http://github.com/joshrivers/FreeSWITCH.Managed

The first thing I did was make it _really_ easy to make your own
managed.dll. There's two basic points where managed code attaches to
unmanaged code. If you rewrite the loader class, you can make your own
managed.dll that does anything you want.

The next layer up exposes a simple IOC registry that could be modified to
replace or add to the logging chain, the module loading chain, or the
command execution chain.

Beyond that, appdomain loading, script compilation, and inside-appdomain
plugin loading are all plugabble.

Current plugins should all remain compatible (mine at least haven't needed a
recompile).

What needs to be done:
- There are a few changes in SVN that need to be integrated with my fork.
- A lot more unit testing would be useful.
- There should be a mechanism for indicating that a script or dll should be
pre-loaded into all other appdomains (as a mechanism for defining new plugin
types).
- There should also be a mechanism for loading a script or dll into the
primary appdomain (to allow your code to modify the core operation of
mod_managed without recompiling the dll)

Most of this should be simple, but I thought it was high time that I got
some feedback. I think this model makes it possible to much more simply add
new functionality to mod_managed allowing coders to establish their own
plugin models and use frameworks such as StructureMap, Spring.NET, MEF, WCF,
or Workflow to create their voip applications.

Let me know what you think,
Josh

On Fri, Sep 11, 2009 at 12:55 AM, Raffaele P. Guidi <
raffaele.p.guidi at gmail.com> wrote:

> *I want to move ILoadNotificationPlugin from being this “catch all” thing
> that controls the entire assembly to something that can be used to fire up
> code; effectively “OnLoad” and “OnUnload”. To dynamically control loading,
> we’ll probably reflect on the individual plugins looking for attributes or
> perhaps some sort of static load function.*
> I meant to do something like that probably using spring to inject method
> names to be invoked. Also event listening (wich is I believe a generic need)
> could be managed this way and benefit from some abstraction. con.pop(1) is
> probably the most frequently written line by every plugin developer,
> probably some abstraction (an event started with his thread and the fs event
> passed as an argument?) could make code more elegant
>
>
> On Fri, Sep 11, 2009 at 00:19, Michael Giagnocavo <mgg at giagnocavo.net>wrote:
>
>>  Well, we have absolutely no idea what the background thread is doing. It
>> might be critical, and the fix is trivial: put a try/catch on it. This is
>> the model all .NET applications have. Background threads doing bad things
>> should always take down the process.
>>
>>
>>
>> However, that’s a good point about Load() failing. The approach taken is
>> more or less how FreeSWITCH handles things in general now. If a module has
>> an error, the switch just logs and goes on. I’m not really in favour of
>> this, and suggested at least a “required” attribute in the modules.conf that
>> would prevent the switch from loading if the module fails.
>>
>>
>>
>> The fix is probably to create an attribute you can apply to the plugin
>> classes that indicate what kind of failure handling you want. For the
>> assembly, we’d add an attribute with an enumeration like:
>>
>> -          Default (scan, call ILoadNotificationPlugin, log errors if
>> they occur)
>>
>> -          NoLoad (don’t load the assembly)
>>
>> -          Critical (stop the switch if there’s an exception during
>> loading)
>>
>>
>>
>> That’d provide the control you want for loading. We could do something
>> similar for App/Api plugins.
>>
>>
>>
>> I want to move ILoadNotificationPlugin from being this “catch all” thing
>> that controls the entire assembly to something that can be used to fire up
>> code; effectively “OnLoad” and “OnUnload”. To dynamically control loading,
>> we’ll probably reflect on the individual plugins looking for attributes or
>> perhaps some sort of static load function.
>>
>>
>>
>> How’s that sound?
>>
>>
>>
>>
>>
>> *From:* freeswitch-users-bounces at lists.freeswitch.org [mailto:
>> freeswitch-users-bounces at lists.freeswitch.org] *On Behalf Of *Josh Rivers
>> *Sent:* Thursday, September 10, 2009 12:48 PM
>>
>> *To:* freeswitch-users at lists.freeswitch.org
>> *Subject:* Re: [Freeswitch-users] Subscribing to events in managed C# /
>> .NET
>>
>>
>>
>> I'm only concerned with the difference in treatment.
>>
>> public class CrashFreeSWITCH : ILoadNotificationPlugin
>>     {
>>         public bool Load()
>>         {
>>             ThreadPool.QueueUserWorkItem((o) => { throw new
>> NotImplementedException(); });
>>             return true;
>>         }
>>     }
>>
>> Crashes the entire switch, terminating all calls and disconnecting from
>> the PSTN.
>>
>> public class CrashFreeSWITCH : ILoadNotificationPlugin
>>     {
>>         public bool Load()
>>         {
>>             throw new NotImplementedException();
>>             return true;
>>         }
>>     }
>>
>> Logs a message to the console and doesn't load the module, while leaving
>> the switch operating.
>>
>>
>>
>> In my experience, exceptions in multi-threaded code: a) happen, b) are
>> hard to diagnose. Is the best behavior for the environment to crash,
>> providing no diagnostic information? That's hard in development, and even
>> harder in production. I suppose 'terminate switch on fault' should be an
>> option, to allow the operating system to restart the whole process on fault
>> conditions, but if that is the intended result, shouldn't any fault do the
>> same thing? What if the billing was happening in my second code block?
>>
>>
>>
>> Normally, I'd trap the ThreadException and UnhandledExceptions in my
>> application, so that my code could choose the correct actions to perform
>> should the application get into an unknown state. This can include
>> terminating the whole application, but also logging diagnostic information,
>> trying to save uncommitted data, and sending notifications of the failure.
>>
>>
>>
>> Is 'crash if it's a thread, but not if it's not' good because it's the way
>> the module works now, or is it a better design for a reason I'm not
>> understanding?
>>
>>
>>
>> On Wed, Sep 9, 2009 at 11:09 PM, Michael Giagnocavo <mgg at giagnocavo.net>
>> wrote:
>>
>> Well, a segfault in voicemail would do the same thing.
>>
>>
>>
>> Suppose your plugin runs a thread that does something important, like
>> billing or so on. That thread fails – do you really want it to go on?
>>
>>
>>
>> Anyways, the solution is simple enough, handle your exceptions J. Every
>> plugin can decide what it wants to do here.
>>
>>
>>
>> -Michael
>>
>>
>>
>> *From:* freeswitch-users-bounces at lists.freeswitch.org [mailto:
>> freeswitch-users-bounces at lists.freeswitch.org] *On Behalf Of *Josh Rivers
>> *Sent:* Wednesday, September 09, 2009 10:41 PM
>>
>>
>> *To:* freeswitch-users at lists.freeswitch.org
>> *Subject:* Re: [Freeswitch-users] Subscribing to events in managed C# /
>> .NET
>>
>>
>>
>> The question is whether the CLR should take down the whole phone server
>> due to an unhandled exception...definitely the CLR should terminate...but
>> shouldn't it just log the exception to the console, not crash the core?
>>
>> On Wed, Sep 9, 2009 at 6:30 PM, Michael Giagnocavo <mgg at giagnocavo.net>
>> wrote:
>>
>> That’s by design. If a thread fails, and there’s no handler, then the
>> application could be in a corrupted state, so the CLR takes down the
>> process.
>>
>>
>>
>> I think there is a .NET 1.0 compat switch you can enable in the config if
>> you like exceptions to be silently ignored J.
>>
>>
>>
>> -Michael
>>
>>
>>
>> *From:* freeswitch-users-bounces at lists.freeswitch.org [mailto:
>> freeswitch-users-bounces at lists.freeswitch.org] *On Behalf Of *Josh Rivers
>> *Sent:* Wednesday, September 09, 2009 6:39 PM
>>
>>
>> *To:* freeswitch-users at lists.freeswitch.org
>> *Subject:* Re: [Freeswitch-users] Subscribing to events in managed C# /
>> .NET
>>
>>
>>
>> I have a new thought on the crashes...I'm able to crash FreeSWITCH any
>> time I like, just by having an exception in a thread.
>>
>>
>>
>>     public class CrashFreeSWITCH : ILoadNotificationPlugin
>>
>>     {
>>
>>         public bool Load()
>>
>>         {
>>
>>             ThreadPool.QueueUserWorkItem((o) => { throw new
>> NotImplementedException(); });
>>
>>             return true;
>>
>>         }
>>
>>     }
>>
>>
>>
>> Perhaps Application.ThreadException or AppDomain.UnhandledException need
>> to be trapped?
>>
>>
>>
>> On Wed, Sep 9, 2009 at 4:51 PM, Michael Giagnocavo <mgg at giagnocavo.net>
>> wrote:
>>
>> >Looks like the event object goes straight to pinvokes, so a null result
>> just crashes?
>>
>>
>>
>> If it’s null, you should get a NullReferenceException. The C# compiler
>> should callvirt the property getter and that’ll do a null check. If that
>> isn’t happening, that’d be an interesting optimization somewhere along the
>> line.
>>
>>
>>
>> -Michael
>>
>>
>>
>>
>>
>> *From:* freeswitch-users-bounces at lists.freeswitch.org [mailto:
>> freeswitch-users-bounces at lists.freeswitch.org] *On Behalf Of *Josh Rivers
>> *Sent:* Wednesday, September 09, 2009 3:01 PM
>>
>>
>> *To:* freeswitch-users at lists.freeswitch.org
>>
>> *Subject:* Re: [Freeswitch-users] Subscribing to events in managed C# /
>> .NET
>>
>>
>>
>> A new discovery:
>>
>>         public bool Load()
>>
>>         {
>>
>>             ThreadPool.QueueUserWorkItem((o) =>
>>
>>             {
>>
>>                 Log.WriteLine(LogLevel.Notice, "Thread Starting. ");
>>
>>                 EventConsumer con = new EventConsumer("all", "");
>>
>>                 while (true)
>>
>>                 {
>>
>>                     Event ev = con.pop(0);
>>
>>                     if (ev == null) continue;
>>
>>                     Log.WriteLine(LogLevel.Notice, "Event: " +
>> ev.serialized_string);
>>
>>                 }
>>
>>             });
>>
>>             return true;
>>
>>         }
>>
>> Does not crash. (Adding the null check prevents crash.) The backgrounded
>> loop runs fine. Looks like the event object goes straight to pinvokes, so a
>> null result just crashes?
>>
>>
>>
>> I like the idea of a 'startup-script' for mod_managed. It would also be
>> excellent if there was an event or message  informing the background code to
>> terminate nicely when the module reloads.
>>
>>
>>
>> --Josh
>>
>>
>>
>> On Wed, Sep 9, 2009 at 12:57 PM, Jeff Lenk <jlenk at frontiernet.net> wrote:
>>
>>
>> I think the problem here is that the loader only keeps this method in
>> scope
>> until completion then it drops the remoted connection. Therefore you
>> should
>> not use threads in this method. Michael please correct me if I am wrong
>> here.
>>
>> As an example of the failure simply just put a Sleep(10000) call in the
>> thread and you will see the failure.
>>
>> As Michael said this method was only designed to allow the option to opt
>> out
>> of being loaded.
>>
>> In order to support this perhaps a configuration flag simular to the lua
>> "startup-script" should be added.
>>
>>
>>
>>
>> Here is the error I get with the loop I mentioned. -Josh
>> [image: Capture.PNG]
>>
>> On Tue, Sep 8, 2009 at 5:05 AM, Michael Giagnocavo
>> <mgg at giagnocavo.net>wrote:
>>
>> >  Hi,
>> >
>> >
>> >
>> >                 Can you please elaborate on the crash you receive when
>> you
>> > queue a thread during load?
>> >
>> >
>> >
>> > Thanks,
>> >
>> > Michael
>> >
>> >
>>
>> --
>> View this message in context:
>> http://n2.nabble.com/Subscribing-to-events-in-managed-C-NET-tp3573619p3613195.html
>> Sent from the freeswitch-users mailing list archive at Nabble.com.
>>
>>
>> _______________________________________________
>> FreeSWITCH-users mailing list
>> FreeSWITCH-users at lists.freeswitch.org
>> http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
>> UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
>> http://www.freeswitch.org
>>
>>
>>
>>
>> _______________________________________________
>> FreeSWITCH-users mailing list
>> FreeSWITCH-users at lists.freeswitch.org
>> http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
>> UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
>> http://www.freeswitch.org
>>
>>
>>
>>
>> _______________________________________________
>> FreeSWITCH-users mailing list
>> FreeSWITCH-users at lists.freeswitch.org
>> http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
>> UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
>> http://www.freeswitch.org
>>
>>
>>
>>
>> _______________________________________________
>> FreeSWITCH-users mailing list
>> FreeSWITCH-users at lists.freeswitch.org
>> http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
>> UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
>> http://www.freeswitch.org
>>
>>
>>
>> _______________________________________________
>> FreeSWITCH-users mailing list
>> FreeSWITCH-users at lists.freeswitch.org
>> http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
>> UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
>> http://www.freeswitch.org
>>
>>
>
> _______________________________________________
> FreeSWITCH-users mailing list
> FreeSWITCH-users at lists.freeswitch.org
> http://lists.freeswitch.org/mailman/listinfo/freeswitch-users
> UNSUBSCRIBE:http://lists.freeswitch.org/mailman/options/freeswitch-users
> http://www.freeswitch.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.freeswitch.org/pipermail/freeswitch-users/attachments/20090923/f7b53337/attachment-0002.html 


More information about the FreeSWITCH-users mailing list