flex-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Alex Harui <aha...@adobe.com.INVALID>
Subject Re: Background Worker disposing of failed MessageChannel freezes application
Date Sun, 15 Oct 2017 22:51:31 GMT
Hi,

I was hoping someone with experience with workers would answer.  I haven't
worked with them myself.

Is it possible for the worker to not kill itself in an event handler, or
at least, in a CHANNEL_MESSAGE handler?  Maybe set a flag to stop doing
more work and either kill itself 'later' or ask the main thread to kill it?

Maybe the Flash runtime isn't prepared for a worker to go away in certain
situations.

HTH,
-Alex

On 10/15/17, 6:20 AM, "Michael Schwarz" <michael.schwarz93@googlemail.com>
wrote:

>Hi everyone,
>
>sorry for resending this, but I still have the same issue.
>Is there another mailing list or online community you could recommend that
>might have an answer to this question? Or is there a way to improve my
>question to make it easier to help?
>Thanks,
>
>Michael
>
>On Mon, Oct 9, 2017 at 9:22 AM Michael Schwarz <
>michael.schwarz93@googlemail.com> wrote:
>
>> Hi there,
>>
>> I encountered a really strange behavior with Flex and already tried
>> StackOverflow and Reddit, but didn't get any reponse, so I'm trying here
>> again:
>>
>> I have the following scenario: I am using a MessageChannel to
>>communicate
>> with a background worker in a flex application. Since the code is to
>> eventually be transformed into a library, it should also be able to
>>handle
>> malformed input (e.g. sending classes via the channel for which no class
>> alias is registered in the background worker). In this case I want to
>>abort
>> the worker. My code is the following:
>>
>> package{
>>     import flash.display.Sprite;
>>     import flash.events.Event;
>>     import flash.system.MessageChannel;
>>     import flash.system.Worker;
>>
>>     public class BW extends Sprite
>>     {
>>         /** Incoming channel */
>>         private var fromCoordinatorChannel:MessageChannel;
>>
>>         /** Outgoing channel */
>>         private var toCoordinatorChannel:MessageChannel;
>>
>>         public function BW()
>>         {
>>             super();
>>             initChannels();
>>         }
>>
>>         /**
>>          * Get channels from shared property and attach event listener
>>          */
>>         private function initChannels():void {
>>             // Get channnels from shared property
>>             fromCoordinatorChannel =
>>Worker.current.getSharedProperty("toWorkerChannel");
>>             toCoordinatorChannel =
>>Worker.current.getSharedProperty("fromWorkerChannel");
>>
>>             // Attach event listener for incoming messages
>>             
>>fromCoordinatorChannel.addEventListener(Event.CHANNEL_MESSAGE,
>>onIncomingMessage);
>>         }
>>
>>         /**
>>          * Event handler for incoming messages on the channel.
>>          * @param event Event that came in
>>          */
>>         private function onIncomingMessage(event:Event):void {
>>             handleIncoming();
>>         }
>>
>>         /**
>>          * Get oldest message from channel and handle it
>>          */
>>         private function handleIncoming():void {
>>             if(fromCoordinatorChannel.messageAvailable) {
>>                 try {
>>                     var wm:Object =
>>fromCoordinatorChannel.receive(true);
>>                 } catch(e:Error) {
>>                     fromCoordinatorChannel.close();
>>                     trace("Invalid type of package sent - could not be
>>deserialized.");
>>
>>                     // Kill myself
>>                     fromCoordinatorChannel = null;
>>                     toCoordinatorChannel = null;
>>                     Worker.current.setSharedProperty("toWorkerChannel",
>>null);
>>                 
>>Worker.current.setSharedProperty("fromWorkerChannel", null);
>>
>>                     Worker.current.terminate();
>>                 }
>>             }
>>         }
>>     }}
>>
>> And in the primordial worker:
>>
>> <?xml version="1.0" encoding="utf-8"?><s:WindowedApplication
>>xmlns:fx="https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2
>>Fns.adobe.com%2Fmxml%2F2009&data=02%7C01%7C%7C8210af64a1fe4e2a8f2808d513c
>>f93fd%7Cfa7b1b5a7b34438794aed2c178decee1%7C0%7C0%7C636436704640671187&sda
>>ta=Kjlgy55n9mnR9aUt9aAQuMy5%2BIMUd%2F8ZWUp1E8ZLF%2Fg%3D&reserved=0"
>>                        xmlns:s="library://ns.adobe.com/flex/spark"
>>                        xmlns:mx="library://ns.adobe.com/flex/mx">
>>     <fx:Script>
>>         <![CDATA[
>>             import mx.events.FlexEvent;
>>
>>             var worker:Worker;
>>             var to:MessageChannel;
>>             var from:MessageChannel;
>>
>>             var graveyard:Array = new Array();
>>
>>
>>             private function removeWorkerIfFailed():void {
>>                 if(worker && worker.state == WorkerState.TERMINATED) {
>>                     from.close();
>>                     worker = null;
>>
>>                     // What the actual f***? If I allow this channel to
>>be garbage collected, it breaks. If I prevent that, it doesn't (o.Ó)
>>                     graveyard.push(to);
>>
>>                     to = null;
>>                     from = null;
>>                 }
>>             }
>>
>>
>>             protected function
>>button1_clickHandler(event:MouseEvent):void
>>             {
>>                 registerClassAlias("Example", Example);
>>
>>                 // Create worker and channels
>>                 worker = WorkerDomain.current.createWorker(Workers.BW);
>>                 to = Worker.current.createMessageChannel(worker);
>>                 from = worker.createMessageChannel(Worker.current);
>>
>>                 // Attach event listener to status of worker so its
>>reference can be deleted when it fails
>>                 
>>worker.addEventListener(Event.WORKER_STATE,function(event:Event):void
>>{removeWorkerIfFailed();});
>>
>>                 // Set shared properties so worker can access channels
>>                 worker.setSharedProperty("toWorkerChannel", to);
>>                 worker.setSharedProperty("fromWorkerChannel", from);
>>
>>                 // Attach event listener for incoming messages
>>                 from.addEventListener(Event.CHANNEL_MESSAGE,
>>function(event:Event):void { trace('incoming'); });
>>
>>                 // Start the worker
>>                 worker.start();
>>
>>
>>                 var example1:Example = new Example("one");
>>                 to.send(example1);
>>             }
>>         ]]>
>>     </fx:Script>
>>     <s:Button label="Do it" click="button1_clickHandler(event)">
>>
>>     </s:Button></s:WindowedApplication>
>>
>> Add the Example class
>>
>> package{
>>     import flash.utils.IDataInput;
>>     import flash.utils.IDataOutput;
>>     import flash.utils.IExternalizable;
>>
>>     public class Example implements IExternalizable
>>     {
>>         public var name:String;
>>         public function Example(name
>>
>>

Mime
View raw message