Showing posts with label proxy pattern. Show all posts
Showing posts with label proxy pattern. Show all posts

Sunday, January 24, 2016

Is It a Real Proxy Pattern Without Types?


It turns out that I may be too rigid at times with my types in Dart. That's just insane. Me. An old Perler, an ancient Rubyist, and old-timey JavaScripter, someone who fled Java because of the type craziness — using types too darn often. What a world.

When I first explored protection proxy patterns I almost headed down the path of generic proxies, but decided against it because... types. The particular example that I was using to explore protection proxies probably influence me to a fair extent. I was using a Driver to determine if a particular driver instance was old enough to legally start a Car. I opted against a generic proxy class (probably rightly) since a proxy class protecting against drivers was certain to be an automobile of some kind. Following from there, if the proxy class always worked with automobiles, it might as well implement the Automobile interface.

That suited me just fine because it kept me on the happy Gang of Four path. All of my proxy pattern explorations followed the same patterns as in the original book: a subject (the interface), a real subject (e.g. a Car) and a proxy (e.g. RemoteCar). But in Gilad Bracha's The Dart Programming Language, it struck me reading that, not only was it OK to use a generic proxy, but that "being able to define transparent proxies for any sort of object is an important property."

So, I go back to my protection proxy example to see how it will work with a proxy that will work with any kind of object. In addition the object serving as the real subject of my protection proxy, I also need a driver instance through which access will be allowed or denied:
class ProxyProtect {
  final Driver _driver;
  final _realSubject;

  ProxyProtect(this._driver, this._realSubject);
  // ...
}
As a quick aside, I must point out that I really enjoy Gilad's book. It is wonderful getting insights into the language from one of the primary designers. The little notes about things like variables almost almost always being used in a final way are wonderful. I will make a concerted effort to use final in most of my real code. I likely won't use it teaching for the same reason that it is not the default in the language—it is not expected by most developers. Anyhow...

I have my ProxyProtext constructor, now I need the calls to the real subject. I continue to use noSuchMethod() for this:
import 'dart:mirrors' show reflect;

@proxy class ProxyProtect {
  // ...
  dynamic noSuchMethod(i) {
    if (_driver.age <= 16)
      throw new IllegalDriverException(_driver, "too young");

    return reflect(_realSubject).delegate(i);
  }
}
If no other methods are defined, then Dart will invoke noSuchMethod() with information about the method being invoked. With that, no matter what method is invoked, I first check the driver. If the driver is too young, an exception is thrown and nothing else occurs. The real subject is protected against illegal actions. If the driver is of age, then it is time for mirrors—the kind that allow dynamic calls and inspection. In this case, I get a mirror of the real subject with reflect(), then delegate whatever was invoked to the real subject with delegate().

Easy peasy. Now I have a ProxyProtect for any object that might have a driver: a car, an R/C toy, a train, as spaceship, etc. If I create a car and an of-age driver in client code, I can drive the car:

  var _car = new Car(),
      _driver = new Driver(25);
  print("* $_driver here:");

  var car = new ProxyProtect(_driver, _car);
  car.drive();
When run, this results in:
$ ./bin/drive.dart
* 25 year-old driver here:
Car has been driven!
If an underage drive attempts to pilot the vehicle:
  var _car = new Car(),
      _driver = new Driver(16);
  print("* $_driver here:");

  var car = new ProxyProtect(_driver, _car);
  car.drive();
Then this results in:
$ ./bin/drive.dart
* 16 year-old driver here:
Unhandled exception:
IllegalDriverException: 16 year-old driver is too young!
As I found out last night, I am not quite done here. When I run the code through the Dart static type analyzer, I find that my protection proxy does not seem to fit the correct types. Specifically, a drive() method is being invoked when one is not declared and the class does not explicitly specify an interface that it is implementing:
[hint] The method 'drive' is not defined for the class 'ProxyProtect' (/home/chris/repos/design-patterns-in-dart/proxy/bin/drive.dart, line 19, col 7)
To address this, I use the built-in @proxy annotation, which tells the analyzer to give my proxy class a pass:
@proxy class ProxyProtect {
  // ...
}
With that, I have a working protection proxy for any sort of object... and it passes static type analysis. Nothing too surprising here, though I do have figure out how and if to work this into the discussion of the pattern in Design Patterns in Dart. For now, I think I may be done with my exploration of the proxy pattern—it was a fun one! Play with the code on DartPad: https://dartpad.dartlang.org/6d8f76cab3f9d1bb97ff. Day #74

Saturday, January 23, 2016

A Closer Look at the Proxy Annotation in Dart


I don't think I used it once. I enjoyed exploring the proxy pattern in Dart. Trying to use isolates for simple remote proxies was probably ill-advised, but aside from that, my exploration went swimmingly. Except one thing that I was sure would happen never did.

Not once did I use the @proxy annotation for any of my proxy implementations. I am pretty sure that I understand what the @proxy annotation does, but "pretty sure" pretty much always translates into some mistake on my part. And since I never once had to use it when implementing a variety of proxy classes, there is a good chance that I have a knowledge gap.

I had always assumed that @proxy annotated a class indicating that the class supported methods even if not specifically declared. Since Dart is optionally typed, this would be a static type analysis warning, not a compile or runtime issue. But I specifically run all my code through dartanalyzer before using it, so how did I avoid it?

There would have been no need for the annotation with my websocket remote car implementation. All of the methods that were declared in the interface:
abstract class AsyncAuto {
  String get state;
  Future drive();
  Future stop();
}
Were explicitly declared in the remote proxy class:
class ProxyCar implements AsyncAuto {
  // ...
  String get state => _state;
  Future drive() => _send('drive');
  Future stop()  => _send('stop');
  // ...
}
But how did I manage to avoid @proxy with my noSuchMethod() / protection proxy class? In that example, I was still working with cars, but the subject of the pattern, the Automobile interface, only declared a single method:
abstract class Automobile {
  void drive();
}
The proxy class in this example does not explicitly declare the drive method even though it implements the Automobile interface:
class ProxyCar implements Automobile {
  Driver _driver;
  Car _car;

  ProxyCar(this._driver);

  Car get car => _car ??= new Car();

  dynamic noSuchMethod(i) {
    if (_driver.age <= 16)
      throw new IllegalDriverException(_driver, "too young");

    return reflect(car).delegate(i);
  }
}
Without explicitly declaring drive(), I need @proxy, right? Well.. no. When I run dartanalyzer against this library and some client code, I get no issues in either:
$ dartanalyzer bin/drive.dart lib/car.dart
Analyzing [bin/drive.dart, lib/car.dart]...
No issues found
No issues found
I also get no errors when using this DartPad, so this seems to be expected and / or desired behavior. So what is the point of @proxy then? As far as I can tell, it comes in handy when I lack a subject in the proxy pattern. That is, when you do not have an interface to implement, then warning will be issued. For example, if I remove the implements clause from the ProxyCar implementation, but leave the same noSuchMethod() implementation in place:
class ProxyCar {
  // ...
  dynamic noSuchMethod(i) {
    if (_driver.age <= 16)
      throw new IllegalDriverException(_driver, "too young");

    return reflect(car).delegate(i);
  }
}
Then my client code:
  // ...
  car = new ProxyCar(new Driver(25));
  car.drive();
  // ...
Generates warnings:
$ dartanalyzer bin/drive.dart lib/car.dart
Analyzing [bin/drive.dart, lib/car.dart]...
[hint] The method 'drive' is not defined for the class 'ProxyCar' (/home/chris/repos/design-patterns-in-dart/proxy/bin/drive.dart, line 11, col 7)
1 hint found.
In this situation, I can eliminate the warning with a @proxy annotation before the class:
@proxy
class ProxyCar {
  // ...
}
But, as long as I have an interface to implement and a noSuchMethod() method declared, @proxy is not necessary. In The Dart Programming Language, Gilad Bracha has a nice explanation of why one might want a proxy without a classic subject. I may take a closer look at that tomorrow. For now, I have a better understanding of @proxy and why it usually is not necessary.

Play with the non-annotated code on DartPad: https://dartpad.dartlang.org/3577ddd84876ebf310c4.

Day #73

Friday, January 22, 2016

Program to Distant Interfaces


For the most part I am content to create Dart examples that run in the SDK. Command-line scripts feel lighter than their browser-based counterparts (and are certainly lighter than their JavaScript compiled counterparts). Plus, I can usually convert my scripts to run on DartPad. But I feel compelled to try my remote proxy pattern websocket implementation in the browser—not because I fear something going wrong. Rather, I am curious to explore coding to an interface in two different locations.

I create a simple web/index.html page to hold a remote proxy car instance. As UIs go, this barely qualifies as bare minimum:



Still, it should be sufficient to test things out.

Surprisingly (at least to me) things go amiss here. I had forgotten that the WebSocket class in the dart:html library differs from the one that I had been using in dart:io. The former conforms to the standard browser websocket interface where the latter is a standard Stream implementation.

Aside from the annoyance of two different interfaces for the same object, there are some practical differences for which I have to account. In the drive.dart script pulled into the web page via <script> tag, I have to add a Completer to await the websocket being ready for use:
import 'dart:async' show Completer;
import 'dart:html' show WebSocket, document, query;

import 'package:proxy_code/web_car.dart';

main() async {
  var socket = new WebSocket('ws://localhost:4040/ws');

  var _c = new Completer();
  socket.onOpen.listen((_){ _c.complete(); });
  await _c.future;

  // Create proxy car with send/receive streams
  ProxyCar car = new ProxyCar(socket);
  // ...
}
The web_car.dart file with the web remote proxy implementation also needs to change slightly, listening to the onMessage property instead of directly to the socket:
class ProxyCar implements AsyncAuto {
  // ...
  ProxyCar(this._socket) {
    _socket.onMessage.listen((e) {
      _state = e.data;
    });
  }
  // ...
}
But once those minor differences are sorted out, everything just works. Darn it.

I hook up the buttons in the page to event listeners in the Dart script:
  document.query('#drive').onClick.listen((_) async {
    print('Drive');
    await car.drive();
    updateState(car.state);
  });
Clicking the button tells the proxy car to drive, which then results in an update to the state from the websocket. The result of this is included in the <pre> tag below the buttons:



And, indeed, the web socket server from the other night is seeing these messages and passing them along to the real car:
$ ./bin/server.dart
[AsyncCar] received: stop
[AsyncCar] received: drive
In the sum total of things, that is a good thing. I was able to take my command-line remote proxy package and use it in the browser with only minor changes. I hadn't counted on those minor changes between websocket implementations. And I had expected that I would need to move the common interface out into a separate file that could be imported into both dart:io and dart:html libraries. That turned out not be necessary--thanks to Dart's beautiful libraries and creating the websockets in the client instead of the libraries.

Since libraries work so well in this case, I have no doubt that they will work when the common subject interface is pulled out into its own file. I do it anyway, creating interface.dart with:
library car;

import 'dart:async' show Future;

// Subject
abstract class AsyncAuto implements Automobile {
  String get state;
  Future drive();
  Future stop();
}
I then import that into both real_car.dart and web_car.dart:
library car;

import 'dart:async' show Future, Stream;
import 'dart:html' show WebSocket;

import 'interface.dart';

// Proxy Subject
class ProxyCar implements AsyncAuto {
  // ...
}
That makes the type analyzer happy and positions me well should I ever decide to create the specific websockets implementations in the dart:html and dart:io libraries. In other words, no matter how I decide I want to code those implementations, I have easy access to the interface to program against.


Day #72


Thursday, January 21, 2016

Full-Duplex Streams


I ask you, what kind of world do we live in where websockets are the easy answer?

Sure, my problems are my own and completely contrived, but still, websockets have proven to be the ideal medium to describe the remote proxy pattern. What makes them so nice is that I only have to supply a single socket to the proxy instance in order to enable it to control a real subject:
main() async {
  var socket = await WebSocket.connect('ws://localhost:4040/ws');
  ProxyCar car = new ProxyCar(socket);
  // ...
}
The reason that this works is that websockets are, under the covers, a full-duplex communication channel. That is, a single websocket supports messages going from the client to the server and from the server to the client.

Just as importantly, websockets send bi-directional messages rather than broadcast messages. Streams in Dart are either one-way or broadcast. I had previously attempted the remote proxy pattern with streams, but that required two streams, one for inbound and one for outbound:
main() async {
  var mainOut = new StreamController(),
      mainIn = new StreamController();
  ProxyCar car = new ProxyCar(mainOut, mainIn);
  // ...
}
It works and, if you think about the need for sending messages from the client to the server and vice versa, that approach makes sense. But if I am trying to describe this in a book like Design Patterns in Dart, I don't want readers to have to think about this—just the core concept being discussed.

And don't even get me started on communication via isolate workers. They are twice as conceptually complex due to the need to create communication channels over existing one-way channels.

And so, yes, I have created a world for myself in which websockets are the neat and clean answer. Armageddon must soon surely follow.

But seriously, I am not diametrically opposed to websockets for this case. They do make a certain amount of sense as a vehicle for remotely controlling cars or other objects. I had hoped to find another kind of stream in the standard Dart library that was full-duplex, but that would appear not possible.

Websockets in Dart are streams and they implement the Stream interface (for listening to messages) and the StreamSink interface (for sending messages). I had hoped that StreamSink might be implemented by another class that happened to be full-duplex. But it is only implemented by the StreamController that previously forced me into the undesirable two-stream-instances implementation.

But what if I try it with just a single stream instead?
main() async {
  var socket = new StreamController.broadcast();
  ProxyCar car = new ProxyCar(socket);
  // ...
}
The socket needs to be a broadcast stream so that both the proxy and real subject can listen to the same stream. Of course that is going to cause problems since ProxyCar will see messages from the real car and itself. So I need a way for ProxyCar to ignore its own messages.

I could use an enum here or some other lookup, but it turns out that I already have a convention in place. The ProxyCar class only sends commands to the real car. I am sending those as symbols instead of strings (because mirrors!):
class ProxyCar implements AsyncAuto {
  // ...
  Future drive() => _send(#drive);
  Future stop()  => _send(#stop);

  Future _send(message) {
    _socket.add(message);
    // ...
  }
}
So when ProxyCar listens for messages on the broadcast "socket," I can filter out any symbol messages with where():
class ProxyCar implements AsyncAuto {
  StreamController _socket;
  String _state = "???";

  ProxyCar(this._socket) {
    _socket.stream.where((m)=> m is! Symbol).listen((message) {
      print("[ProxyCar] $message");
      _state = message;
    });
  }
  // ...
}
Conversely, the real car, AsyncCar, only sends strings, so it can filter those out:
class AsyncCar implements AsyncAuto {
  StreamController _socket;
  Car _car;

  AsyncCar(this._socket) {
    _car = new Car();

    _socket.stream.where((m)=> m is! String).listen((message) {
      print("[AsyncCar] $message");
      if (message == #drive) _car.drive();
      if (message == #stop)  _car.stop();
      _socket.add(state);
    });
  }
  // ...
}
That works, and is nicer than creating two explicit instances. There is no need for mention of full-duplex communication should I include this in the book—I can merely mention that these classes need to ignore their own messages. The best part of this solution is that it works on DartPad:

https://dartpad.dartlang.org/aef966876bda192076c0

Still, crazy as it seems, this is not as nice as websockets which require no explanation other than "they send messages back and forth between client and server." So, unless I really need DartPad or another requirement presents itself, it looks like I love me some websockets.


Day #71

Wednesday, January 20, 2016

Driving Cars with Websockets


Isolates look unlikely to serve as a teachable implementation for the remote proxy pattern in Dart. They are relatively simple, but still remain a tad too cumbersome. Last night's exploration of simple streams shows promise, begging the question of how another stream might work—websockets.

I borrow (OK, steal verbatim) the example websocket server from the Dart on the server example:
#!/usr/bin/env dart

import 'dart:async';
import 'dart:io';

handleMsg(msg) {
  print('Message received: $msg');
}

main() {
  runZoned(() async {
    var server = await HttpServer.bind('localhost', 4040);
    await for (var req in server) {
      if (req.uri.path == '/ws') {
        // Upgrade a HttpRequest to a WebSocket connection.
        var socket = await WebSocketTransformer.upgrade(req);
        socket.listen(handleMsg);
      };
    }
  },
  onError: (e) => print("An error occurred: $e"));
}
I will add my proxy pattern code shortly. For now, I just want to ensure that it works. I save this as bin/server.dart, chmod 755 and start it up with ./bin/server.dart. Nothing crashes, so I assume that I am good to go.

In my existing proxy pattern script, I add the appropriate websocket client code:
#!/usr/bin/env dart

import 'dart:async';
import 'dart:io';

main() async {
  var socket = await WebSocket.connect('ws://localhost:4040/ws');
  socket.add('Hello, World!');
  // ...
}
That should connect to my running websocket server and add a message to the websocket stream to which the server is currently listening. When I run this client script, I see the following message from the server:
$ ./bin/server.dart
Message received: Hello, World!
Nice! Web sockets were never all that hard in Dart, but they are getting close to trivial.

So what is it going to take to convert my ProxyCar from streams (which were converted last night from isolates) to websockets? Blood sacrifice? The answer is surprisingly little.

In my client code, I continue to open the websocket, pass that to a ProxyCar, then perform some remote car operations:
main() async {
  var socket = await WebSocket.connect('ws://localhost:4040/ws');

  ProxyCar car = new ProxyCar(socket);

  print("Attempting to drive remote car...");
  await car.drive();
  print("Car is ${car.state}");

  print("--");

  print("Attempting to stop remote car...");
  await car.stop();
  print("Car is ${await car.state}");
}
The ProxyCar is responsible for listening to this websocket for state responses from the real car. I establish that listener in the constructor:
class ProxyCar implements AsyncAuto {
  Stream _socket, _broadcast;
  String _state;

  ProxyCar(this._socket) {
    _broadcast = _socket.asBroadcastStream();
    _broadcast.listen((message) {
      _state = message;
    });
  }
  // ...
}
I get a broadcast version of the websocket so that I can listen to it in multiple locations. Here, I listen for state updates. When I send action messages to the real car, I also listen to the stream for confirmation that the message was received:
class ProxyCar implements AsyncAuto {
  Stream _socket, _broadcast;
  String _state;
  // ...
  String get state => _state;
  Future drive() => _send('drive');
  Future stop()  => _send('stop');

  Future _send(message) {
    _socket.add(message);
    return _broadcast.first;
  }
}
I may reconsider that at some point, just for ease of discussion. For now, I leave it as-is.

The server is using the same library. Instead of the ProxyCar instance, it works with the real subject in this pattern: an AsynCar instance:
      // ...
      if (req.uri.path == '/ws') {
        // Upgrade a HttpRequest to a WebSocket connection.
        var socket = await WebSocketTransformer.upgrade(req);
        new AsyncCar(socket);
      };
      // ...
Like the ProxyCar, the AsyncCar implements the AsyncAuto interface:
// Subject
abstract class AsyncAuto implements Automobile {
  String get state;
  Future drive();
  Future stop();
}
If anything, the AsyncCar real subject is even simpler than the proxy:
class AsyncCar implements AsyncAuto {
  Stream _socket;
  Car _car;

  AsyncCar(this._socket) {
    _car = new Car();

    _socket.listen((message) {
      print("[AsyncCar] received: $message");
      if (message == 'drive') _car.drive();
      if (message == 'stop')  _car.stop();
      _socket.add(state);
    });
  }

  String get state => _car.state;
  Future drive() => new Future((){ _car.drive(); });
  Future stop()  => new Future((){ _car.stop(); });
}
It adapts a synchronous Car, which it manipulates in response to messages that it receives from the socket. If the websocket message is 'drive', then the car instance is sent the drive message. If the websocket see 'stop', stop() is invoked on car.

And that actually works. Running the client code results in:
$ ./bin/drive.dart
Attempting to drive remote car...
Car is driving
--
Attempting to stop remote car...
Car is idle
Checking the server output, I see:
$ ./bin/server.dart
[AsyncCar] received: drive
[AsyncCar] received: stop
So there you have it. I can drive a car over websockets with Dart. And it was pretty darn easy!


Day #70

Tuesday, January 19, 2016

Faking Dart Isolates for Proxy Pattern Profits


Perhaps the best answer is "not."

I have been struggling with how best to present isolates (isolated workers) as a remote proxy pattern vehicle. As of last night, I think I have the bare minimum of what I can do in my Dart code. It's good—functional, well named, proper—but still complex enough that it would distract from the main discussion.

So what if I get rid of isolates altogether? Well, for one thing, I likely would not really need a remote proxy pattern implementation. The main function could speak directly to the worker function without required go-betweens like send and receive ports. For the sake of argument and illustration, let's stipulate that there is a requirement for main and worker functions to speak only over streams.

I start by replacing the isolate / send-port / receive-post dance with two stream controllers in main()—one for sending messages to the worker function, the other for receiving messages from the worker:
main() async {
  var mainOut = new StreamController.broadcast(),
      mainIn = new StreamController.broadcast();
  // ...
}
Next, I create a remote ProxyCar instance, supplying these two stream controllers for communication with the real subject (which will reside in the worker() function):
main() async {
  var mainOut = new StreamController.broadcast(),
      mainIn = new StreamController.broadcast();

  // Create proxy car with send/receive streams
  ProxyCar car = new ProxyCar(mainOut, mainIn);
  // ...
}
This requires two minor changes to the ProxyCar declaration, neither of which should really affect ease of understanding. First, the _in and _out instance variables become StreamControllers instead of ReceivePort and SendPort. Second, I need to listen on the StreamController's stream instead of directly on the StreamController object:
class AsyncCar implements AsyncAuto {
  StreamController _out, _in;

  AsyncCar(this._out, this._in) {
    _in.stream.listen((message) {
      print("[AsyncCar] $message");
      if (message == #drive) _car.drive();
      if (message == #stop)  _car.stop();
      _out.add(state);
    });
  }
  // Proxied methods remain unchanged...
}
Back in main(), I also sent the mainOut and mainIn stream controllers to the worker:
  // Start "worker"
  worker(mainIn, mainOut);
Inside the worker() function, these two arguments are mirrors of the arguments in main()mainIn in main() is workerOut inside worker():
worker(StreamController workerOut, StreamController workerIn) {
  new AsyncCar(workerOut, workerIn);
}
The AsyncCar class requires the same minor StreamController changes that I made to ProxyCar, but the actual functionality remains unchanged from the isolate version of the code.

And that does the trick. Back in main(), I can invoke the usual vehicle methods on the ProxyCar and those requests are forwarded onto the real AsyncCar in worker():
main() async {
  var mainOut = new StreamController.broadcast(),
      mainIn = new StreamController.broadcast();

  ProxyCar car = new ProxyCar(mainOut, mainIn);
  worker(mainIn, mainOut);

  await car.drive();
  print("Car is ${car.state}");

  print("--");

  await car.stop();
  print("Car is ${await car.state}");
}
Along with some debugging code inside the car classes, this code produces the following output:
$ ./bin/drive.dart                          
[AsyncCar] Symbol("drive")
[ProxyCar] driving
Car is driving
--
[AsyncCar] Symbol("stop")
[ProxyCar] idle
Car is idle
I like that. The example is certainly contrived, but experienced Dartisans will recognize where this can go while folks new to the language should not be completely lost. Once the main discussion is done, I would then be free to show a quick code transformation into an isolate—or even a web socket—solution.

And best of all is that this approach can be seen on DartPad: https://dartpad.dartlang.org/7cc9f080e49939ac4cad.


Day #69

Monday, January 18, 2016

A Naming Convention for Dart Isolate Ports


I still can't isolate. Well, I can create isolate workers in Dart, but they feel incredibly awkward to use to support programming discussions. I may give up on them, but I'd like at least one more shot at them.

On the face of it, communication between the main entry point and a worker is fairly simple:



Main sends messages from its send-port to the receive-port in the worker. The worker uses its own send-port to send messages to the receive-port back in main. Simple, right? Yes and no.

From the above diagram, you might think that main's receive-port is created last:
  1. first you need a send-port to send to the worker
  2. second, the worker needs a receive port to listen for those messages
  3. third, the worker needs a send-port to send back to main
  4. last, main needs the receive port to listen for messages from worker
In reality, Dart receive-ports are created first. A send-port is just a property of the receive-port. As a property of a receive-port, the send-port is already linked for communication, the challenge is then to get main's receive-port send-port to the worker and vice-versa.

Side-note: sentences like the last one are probably why I will not be able to use isolates in discussions like remote proxy patterns. It makes sense if you noodle it through, but readers should expend cognitive load on the main discussion, not the apparatus for the discussion. Anyway, onward...

To create an isolate worker, the main entry point first creates its receive-port (with associated send-port). It then spawns the worker sending along the associated send-port at the same time:



At this point, the worker can send all the messages it likes back to the main worker, but main has no way to communicate back to worker. In many cases this is just fine. In many of the examples that I want to use, however, this is insufficient. To allow main to communicate with worker, worker has to create its own receive-port and supply the associated send-port back to main. There is only one way to do so—back through main's send-port:



All of this makes perfect sense. I understand the tradeoffs involved. I understand how to set it up. I cannot think of better names than "ports" for these beasties. But the end result is that I have to send a send-port over a send-port in order to establish worker's receive-port. And all I really want is to discuss the proxy pattern, darn it.

I am unsure how to proceed at this point. It seems like a higher level library is in order, but then I have a library just for teaching purposes. Maybe that is what I will wind up doing in the end. First though, I am going to experiment with a worker-centric naming convention to see if it helps the actual code.

So, in worker, I will refer to the send-port (which comes from main) as "worker-out." Back in main, that same send-port will be associated with "main-in":



To make that happen, I start in main() by creating my mainIn receive-port, then sending its sendPort to worker() when it is spawned:
main() async {
  var mainIn = new ReceivePort();
  await Isolate.spawn(worker, mainIn.sendPort);
  // ...
}
(I am using the async / await syntactic sugar for Dart futures here)

So far, so good. I have a good handle on what mainIn is. Previously, I had called that receivePort or just r—by the time I was looking inside worker, I was easily confused. Hopefully this naming convention will serve me better.

Then, down in the worker() that is being spawned, I accept main's mainIn.sendPort, assigning it locally as workerOut:
worker(SendPort workerOut) {
  // ...
}
At the risk of being redundant, from main's perspective, this is mainIn.sendPort. From worker's perspective, that same thing is workerOut. I think that works.

Now I need a workerIn, which is a receive-port and I need to send it back to main:
worker(SendPort workerOut) {
  var workerIn = new ReceivePort();
  workerOut.send(workerIn.sendPort);
  // ...
}
Lastly, back in main, I need to accept that first message and assign it as mainOut. I cannot just ask mainIn for the first message because that has the side-effect of closing the stream and all of this bi-directional communication setup would be for naught. Instead, I convert mainIn from a receive-port to a broadcast stream using the asBroadcastStream() method:
main() async {
  var mainIn = new ReceivePort();
  await Isolate.spawn(worker, mainIn.sendPort);

  var inStream = mainIn.asBroadcastStream();
  SendPort mainOut = await inStream.first;
  // ...
}
With that, I can still listen to inStream for additional communication—even after I have mainOut. Conceptually, this winds up looking something like:



I think I am OK with that. Renaming the ports after the context seems to help clear up most of my confusion. I will likely adopt this approach in future isolate code. That said, I remain unconvinced that this is clear enough for something like Design Patterns in Dart. I may try my hand at a high-level, simple library. I believe that I have already searched for one, but I may also check to see if any existing libraries might suit my needs.

Grist for tomorrow...


Day #68

Sunday, January 17, 2016

Proxies Don't Always Need to Know Subject Type


Up today, I explore types when implementing the proxy pattern in Dart. The Gang of Four book states that proxies do not necessarily need to know the type of the real subject. This seems reasonable to me, but I prefer to at least run the theory through somewhat practical application to see if I am overlooking something.

For the proxy class to not know the type of its real subject, the real subject must be created outside of the proxy and then supplied to the constructor. For the car example that I had been using previously, the client code for this might look something like:
  Automobile realCar =  new Car();
  Automobile proxy = new ProxyAutomobile(realCar);
  proxy.drive();
The proxy class does not need to know the specific class, but it needs to have an interface that is being implemented—the proxy class needs to know that the interface supports a common set of actions.

The subject in this pattern remains the Automobile interface, which declares that all implementations must support the drive() method:
// Subject
abstract class Automobile {
  void drive();
}
Next, I declare three different real subjects that will be used by the proxy class:
// Real Subjects
class Car implements Automobile {
  void drive() {
    print("Car has been driven!");
  }
}

class Truck implements Automobile {
  void drive() {
    print("Truck has been driven!");
  }
}

class Motorcycle implements Automobile {
  void drive() {
    print("Motorcycle has been driven!");
  }
}
The proxy class is still a protection proxy from the other night, so it requires both a type of Automobile and a Driver when constructed:
// Proxy Subject
class ProxyAutomobile implements Automobile {
  Driver _driver;
  Automobile _auto;

  ProxyAutomobile(this._auto, this._driver);
  // ...
}
As for the drive() method itself, it needs to first verify that the driver is legal, then will invoke the drive() method on the real subject:
class ProxyAutomobile implements Automobile {
  // ...
  void drive() {
    if (_driver.age <= 16)
      throw new IllegalDriverException(_driver, "too young");

    _auto.drive();
  }
}
And that works exactly as expected. A driver that is of age can drive any of these automobiles through the proxy class:
  // Proxy will allow access to real subject
  driver = new Driver(25);
  print("== $driver here:");
  new ProxyAutomobile(new Car(),        driver)..drive();
  new ProxyAutomobile(new Truck(),      driver)..drive();
  new ProxyAutomobile(new Motorcycle(), driver)..drive();
The output of that code confirms that the 25 year-old driver can driver each of these:
$ ./bin/drive.dart
== 25 year-old driver here:
Car has been driven!
Truck has been driven!
Motorcycle has been driven!
And a 16 year-old driver results in an illegal driver exception:
  driver = new Driver(16);
  print("== $driver here:");
  new ProxyAutomobile(new Car(), new Driver(16))..drive();
  // => == 16 year-old driver here:
  //    Unhandled exception:
  //    IllegalDriverException: 16 year-old driver is too young!
I mentioned earlier that when the proxy does not know the real subject's type ahead of time, then client code needs to supply the real subject. That is not strictly necessary because... mirrors! Instead of supplying the real subject, the client code can supply the type, or even a symbol representation of the type:
  new ProxyAutomobile(#Car,        driver)..drive();
  new ProxyAutomobile(#Truck,      driver)..drive();
  new ProxyAutomobile(#Motorcycle, driver)..drive();
The proxy class can then use this to create a real subject:
class ProxyAutomobile implements Automobile {
  Driver _driver;
  Symbol _autoType;

  ProxyAutomobile(this._autoType, this._driver);

  Automobile get auto => _autoMirror.reflectee;

  InstanceMirror get _autoMirror =>
    _classMirror.newInstance(new Symbol(''), []);

  ClassMirror get _classMirror =>
    currentMirrorSystem().
      findLibrary(#car).
      declarations[_autoType];

  void drive() {
    if (_driver.age <= 16)
      throw new IllegalDriverException(_driver, "too young");

    auto.drive();
  }
}
Sure that's some gnarly ClassMirrorInstanceMirrrorreflectee code, but it is possible. And some of us really enjoy mirrors for some reason.

I am more or less done with the proxy pattern in Dart now. I may have another go at remote proxies because I was never quite satisfied with my previous efforts. The Gang of Four book also mentions smart references as a possible application of the pattern. I am hard pressed to come up with an illustrative example in a garbage collected language. Regardless, the proxy pattern with unknown types works well.

Play with the (pre-mirror) code on DartPad: https://dartpad.dartlang.org/6a163b3c6708564bb13b.

Day #67

Saturday, January 16, 2016

A Real Virtual Proxy Pattern


Up today, I would like to make my virtual proxy pattern in Dart a little more tangible. Concrete if you will.

Yesterday's example copied shamelessly from the image loading example on the Wikipedia page. Today, I modify it so that, instead of placeholder print() statements, I load actual images on to a page. The context of the image loading proxy pattern is an image gallery. Now, image galleries are the simplest things in the world. Until they aren't.

Consider a personal image collection of 10,000 photos. When the page first loads, it makes sense to load the most recent 100 or so images for display. This is a nice balance between immediate feedback and swamping bandwidth and browser resources. Problems occur if the user immediately scrolls back a few years. The gallery should stop loading those initial images and get to work on the first 100 from a few years back. But if the user missed the date by a month or two, then those images should stop loading and the next batch should start. It turns out to be an interesting challenge, and one that the proxy pattern can help address.

For this exercise, I look at individual images in the gallery. When the image first comes into view, it should display a blank image. After a brief pause (to allow other resources to stop and to ensure the user didn't start scrolling again), the image should load a low resolution version of itself. Lastly, it should load a high resolution version of the photo.

Since there are going to be delays and waiting for loading, I changes the Image interface to return a future when displaying the image:
abstract class Image {
  Future displayImage();
}
The RealImage, which will be the real subject in the pattern, remains relatively unchanged from last night. It is constructed with a filename and then loads that image. Instead of last night's placeholder print() statement, tonight I construct an HTML image element:
class RealImage implements Image {
  String _filename;
 ImageElement img;
  
  RealImage(this._filename) {
    _loadImage();
  }

  void _loadImage() {
    print("Loading    $_filename");
    img = new ImageElement(src: _filename, width: 800, height: 446);
    img.style.border = '1px dashed grey';
    document.body.append(img);
  }
  // ...
}
As for diplayImage(), I still leave this a little rough for ease of illustration. It allows for the _filename to have been changed, updating the ImageElement's src attribute as a means of displaying the image:
lass RealImage implements Image {
  // ...
  Future displayImage() {
    print("Displaying $_filename");
    img.src = _filename;
    return new Future.value();   
  }
}
Were I doing this for real, I would get the Future from a Completer that completes when the image loads. But this will do for now.

Now for the ProxyImage class. I would like to construct this with three filenames / URLs: the tiny version of the image, the low resolution version of the image, and the high resolution of the image. To load the UML diagrams of the proxy pattern from the Wikipedia page, for instance, the ProxyImage creation might look like:
  Image image = new ProxyImage(
    'https://upload.wikimedia.org/wikipedia/commons/5/52/Spacer.gif',
    'https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Proxy_pattern_diagram.svg/320px-Proxy_pattern_diagram.svg.png',
    'https://upload.wikimedia.org/wikipedia/commons/thumb/7/75/Proxy_pattern_diagram.svg/1280px-Proxy_pattern_diagram.svg.png'
  );
To support that, I define three instance variables and require them in the constructor:
class ProxyImage implements Image {
  RealImage _image;
  String _tiny, _lo, _hi;

  ProxyImage(this._tiny, this._lo, this._hi);
  // ...
}
To put a little delay in between loading the different resolutions, I define a simple _pause() helper method:
class ProxyImage implements Image {
  // ...
  Future _pause(int s) {
    var c = new Completer();
    new Timer(new Duration(seconds: s), c.complete);
    return c.future;
  }
}
Given a number, this method returns a future that completes in that number of seconds. With that, I can declare the displayImage() method:
class ProxyImage implements Image {
  // ...
  Future displayImage() async {
    if (_image != null) return _image.displayImage();

    // Start with 1-byte blank image
    _image = new RealImage(_tiny)..displayImage();
    await _pause(1);
    
    // Load the low-res version
    _image
      .._filename = _lo
      ..displayImage();
    await _pause(5);
    
    // Then the hi-res version
    _image
      .._filename = _hi
      ..displayImage();
    return new Future.value();
  }
  // ...
}
Since this is the proxy pattern, this proxy class forwards the proxy method displayImage() to the real subject. In this example, it does so three times for the tiny, low resolution, and high-resolution versions of the image.

I again use the async / await syntax to clean up my Future code here. And clean up it does. After loading the first, tiny image, I await a pause of one second. Then, after loading the second, low resolution image, I await a pause of five seconds. Once that pause is done, the high resolution version of the real image is loaded. Again, I might return a future that completes when the image is loaded, but keep it simple by returning a Future that completes immediately.

And that does the trick. The full, working version of the code is available on DartPad: https://dartpad.dartlang.org/851fe3543e94ec4bb5c0.

When the code is first run, a blank image is displayed. A second later, the low resolution version of the proxy pattern UML diagram displays. Then, 5 seconds after that, the full version displays. If this were part of an image gallery, the ProxyImage instances could be staggered to load at slightly different times from each other. The timers that pause the next higher resolution version of the image could be canceled if the user scrolls the image out of the viewport. All in all, the proxy pattern seems a neat solution for many of the concerns introduced by image galleries.


Day #66

Friday, January 15, 2016

Virtual Proxy Pattern in Dart


Tonight I look at the virtual flavor of the proxy pattern. The Java example on Wikipedia seems a fine place to start. Hopefully this works better than the remote-in-Dart-isolates flavor of the past few days.

I start with the Image interface, which declares that all classes that implement it will sport a displayImage() method:
abstract class Image {
  void displayImage();
}
For this simple example, the RealImage class will have print-to-stdout placeholder methods for actions. The real image needs to be able to load itself from the filesystem when constructed and to display itself when required:
class RealImage implements Image {
  String _filename;

  RealImage(this._filename) {
    _loadImageFromDisk();
  }

  void _loadImageFromDisk() {
    print("Loading    $_filename");
  }

  void displayImage() {
    print("Displaying $_filename");
  }
}
That is simple enough, but it is a nice part of the example. This real subject of the pattern performs an expensive operation when created (or it pretends to). In this case, RealImage loads a large image file from the filesystem.

The project subject, on the other hand, delays expensive operations a long as possible. When created, it stores a reference to the _filename, but only constructs the real image when it has to—when the image needs to display:
class ProxyImage implements Image {
  RealImage _image;
  String _filename;

  ProxyImage(this._filename);

  void displayImage() {
    _image ??= new RealImage(_filename);
    _image.displayImage();
  }
}
The assign-if-null operator (??=) in displayImage() also maintains a reference to the real image should the image need to be displayed a second time.

That is all there is to the basic, virtual proxy. The "virtual" in the name comes from the behavior of the proxy subject—it is very close to behaving in the same manner as the real subject. Aside from the on-demand nature, the two are nearly the same.

And this works as expected. The following main entry point into the code:
main() {
  Image image1 = new ProxyImage("HiRes_10MB_Photo1");
  Image image2 = new ProxyImage("HiRes_10MB_Photo2");

  image1.displayImage(); // loading necessary
  image1.displayImage(); // loading unnecessary
  image2.displayImage(); // loading necessary
  image2.displayImage(); // loading unnecessary
  image1.displayImage(); // loading unnecessary
}
Produces the following output:
$ ./bin/display_images.dart             
Loading    HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Loading    HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo1
I will probably make a go of implementing that for real tomorrow. To better simulate a real image gallery, I might first use a nearly zero-cost blank image:
final BlankImage = new RealImage("blank");
The proxy can display that immediately, then load a not-too-much-higher-cost low resolution version of the image before finally displaying the real thing:
class ProxyImage implements Image {
  // ...
  void displayImage() {
    if (_image != null) return _image.displayImage();

    print("[ProxyImage] cache miss $_filename");
    BlankImage.displayImage();
    new RealImage(_lowFilename)..displayImage();
    _image = new RealImage(_filename)..displayImage();
  }

  String get _lowFilename =>
    _filename.replaceFirst(new RegExp(r'HiRes_\d+\w+_'), 'LoRes_');
}
Running that now produces:
[ProxyImage] cache miss HiRes_10MB_Photo1
Loading    blank
Displaying blank
Loading    LoRes_Photo1
Displaying LoRes_Photo1
Loading    HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
Displaying HiRes_10MB_Photo1
[ProxyImage] cache miss HiRes_10MB_Photo2
Displaying blank
Loading    LoRes_Photo2
Displaying LoRes_Photo2
Loading    HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo2
Displaying HiRes_10MB_Photo1
Each low resolution image is loaded only once, acting as a second (though more helpful) placeholder after the initial blank image. But once the full resolution image is available, it is used going forward. I will give that a go with real images tomorrow. For now...

Play with the code on DartPad: https://dartpad.dartlang.org/22ba8996f50d61cea887.


Day #65

Thursday, January 14, 2016

Cleaning Up that Dart Isolate Mess


I am kinda OK with my current remote proxy pattern implementation in Dart. Sorta.

Actually, the proxy itself is decent, thanks in large part to the async / await syntax introduced the other night:
main() async {
  // Spawn remote isolate worker here...

  ProxyCar car = new ProxyCar(receiveStream, s);

  await car.drive();
  print("Car is ${car.state}");

  await car.stop();
  print("Car is ${await car.state}");
}
Futures and promises are nice constructs, but they sure can get noisy. Dart uses await inside of an async function as syntactic sugar.

That code looks so nice that the code responsible for spawning the isolate worker is bugging me:
main() async {
  var r = new ReceivePort();
  var receiveStream = r.asBroadcastStream();

  await Isolate.spawn(other, r.sendPort);

  SendPort s = await receiveStream.first;

  ProxyCar car = new ProxyCar(receiveStream, s);
  // ...
}
I think I would prefer my client code to look something like:
  ProxyCar car = new ProxyCar();
  await Isolate.spawn(other, car.sendPort);
  await car.ready;
  // ...
I initially try to jam all of the isolate communication code directly into the ProxyCar. As most would expect, that made for a messy ProxyCar. So instead, I define a Talker class to establish a ReceivePort in the current isolate, listen on that same ReceivePort for a SendPort sent by the spawned isolate, and a method for sending messages on that SendPort:
class Talker {
  SendPort _s;
  ReceivePort _r;
  Stream _inStream;
  Future ready;

  Talker() {
    _r = new ReceivePort();
    _inStream = _r.asBroadcastStream();
    ready = _inStream.first.then((message){
      _s = message;
    });
  }

  // For others to talk to us
  SendPort get sendPort => _r.sendPort;

  Future send(message) {
    _s.send(message);
    return _inStream.first;
  }
}
I find myself getting confused by the SendPort from the other isolate and the SendPort that this has to expose for the other isolate to communicate back. As a first pass, I make the SendPort from the other isolate private. It is only used internally as is the ReceivePort for communicating back to Talker. I like that except that the SendPort associated with the private ReceivePort is publicly available. So I get confused. I really want to find better names for these beasties, but I have to admit that "send port" and "receive port" capture the intent as well as anything. Oh well.

With Talker, I can redefine ProxyCar as:
class ProxyCar implements AsyncAuto {
  String state = "???";
  Talker _t;

  ProxyCar() {
    _t = new Talker();
  }

  Future drive() => _send(#drive);
  Future stop()  => _send(#stop);

  SendPort get sendPort => _t.sendPort;
  Future get ready => _t.ready;

  Future _send(message) =>
    _t.
      send(message).
      then((response){
        print("[ProxyCar] $response");
        state = response;
      });
}
That is still a little heavy on the communication side, but I can live with it as all of it delegates to Talker or to the proxied methods (drive(), stop(), etc.).

With that, my original goal is met. The client code becomes simply:
main() async {
  ProxyCar car = new ProxyCar();

  await Isolate.spawn(other, car.sendPort);
  await car.ready;

  await car.drive();
  print("Car is ${car.state}");
  print("--");

  await car.stop();
  print("Car is ${await car.state}");
}
While I like some of this approach, it is proving difficult to explain. I may have to revisit the example or the approach before it is ready for inclusion in Design Patterns in Dart.


Day #64

Wednesday, January 13, 2016

A Real Remote Proxy Across Dart Isolates


My many adventures with the proxy pattern in Dart continues. After day 1, I workable, if ugly code. After day 2, I have nicer, if not-quite-a-proxy-pattern code. So tonight I hope to actually implement a somewhat nice looking version of an actual remote proxy across Dart isolates.

Let's see how I can mess that up.

The setup between the main worker and the isolate worker is pretty typical isolate setup. The main worker holds a ProxyCar and will communicate to a real Car in the isolate. It starts by creating a ReceivePort on which it can listen for messages from the isolate, spawns the isolate, then waits for the first message back from that isolate which will be a SentPort to send messages back to the isolate:
main() async {
  var r = new ReceivePort();
  var receiveStream = r.asBroadcastStream();

  await Isolate.spawn(other, r.sendPort);

  SendPort s = await receiveStream.first;
  // Remote car stuff will follow...
}
Similarly, the other() isolate that holds a real Car instance accepts the SendPort from main() and creates its own ReceivePort to send to main():
other(SendPort s) {
  var r = new ReceivePort();
  var receiveStream = r.asBroadcastStream();
  s.send(r.sendPort);

  new Car(receiveStream, s);
}
Thanks to the very nice async / await syntax in Dart, I was able to clean up a lot of initial async messiness. But now I realize that my remote proxy class does not match the real subject. The ProxyCar class returns Future instances for car actions:
class ProxyCar implements Automobile {
  // ...
  Future drive() => _send(#drive);
  Future stop()  => _send(#stop);
  // ...
}
The real subject (and the interface that both classes implement) declares start() and stop() as returning nothing:
class Car implements Automobile {
  // ...
  void drive() { state = 'driving'; }
  void stop()  { state = 'idle'; }
}
Interestingly (at least to me) is that the Dart type analyzer does not consider this a problem. I would still feel more comfortable if the remote proxy class and the real subject class both implemented the same interface.

There is nothing to be done about the ProxyCar interface. Communication across isolates is inherently asynchronous. So I will experiment with the adapter pattern, adapting a synchronous Car class to an asynchronous version. This might not be the best idea, but...

It does have the advantage of producing a nice, clear Car class:
// Adaptee
class Car implements Automobile {
  String state = 'idle';
  void drive() { state = 'driving'; }
  void stop()  { state = 'idle'; }
}
For the remote proxy, I define a new interface for both the AsyncCar and ProxyCar classes to implement, this time with futury goodness:
// Subject
abstract class AsyncAuto implements Automobile {
  String get state;
  void drive();
  void stop();
}
The AsyncCar class then become both the adapter and real subject. The async messiness as well as the send and receive ports pile into it:
// Real Subject & Adapter
class AsyncCar implements AsyncAuto {
  SendPort _s;
  ReceivePort _r;
  Car _car;
  AsyncCar(this._r, this._s) {
    _car = new Car();

    _r.listen((message) {
      print("[AsyncCar] $message");
      if (message == #drive) _car.drive();
      if (message == #stop)  _car.stop();
      _s.send(state);
    });
  }

  String get state => _car.state;
  Future drive() => new Future((){ _car.drive(); });
  Future stop()  => new Future((){ _car.stop(); });
}
Not much has changed in there from the previous two nights aside from state, drive(), and stop() methods which now forward requests to a concrete Car instance. The drive() and stop() methods also return Future instances for completeness.

Nothing in the ProxyCar class needs to change other than the interface that it implements, which the new AsyncAuto interface:
// Proxy Subject
class ProxyCar implements AsyncAuto {
  // ...
}
Last, I change the isolate to create an AsyncCar:
other(SendPort s) {
  var r = new ReceivePort();
  var receiveStream = r.asBroadcastStream();
  s.send(r.sendPort);

  new AsyncCar(receiveStream, s);
}
With that, I have more traditional version of the remote proxy in which both the remote subject and real subject implement the same interface. I appreciate that the Car class is very clean now. Aside from that, I am unsure that I have bought myself any improvements in code readability or maintainability. So, for now, I would have to rate the benefit of this exercise inconclusive... but fun.


Day #63

Tuesday, January 12, 2016

Await Async Code Cleanup in Dart


My remote proxy pattern solution in Dart got a little off the rails last night. It worked, but the interface changed from a synchronous real subject to an asynchronous proxy subject. Worse, the code was a heap o' Futures.

I do not think there is anything I can do about the asynchronous proxy API—that is simply the nature of remote calls. I do think I can adapt the synchronous interface to an asynchronous interface, then proxy the asynchronous interface. I will investigate that tomorrow. First, I want to clean up the Future heap:
  Isolate.
    spawn(other, r.sendPort).
    then((_) => receiveStream.first).
    then((s) { car = new ProxyCar(receiveStream, s); }).
    then((_) { car.drive(); }).
    then((_) => receiveStream.first).
    then((_) { print("Car is ${car.state}"); }).
    then((_) { car.stop(); }).
    then((_) => receiveStream.first).
    then((_) { print("Car is ${car.state}"); });
That makes sense if you noodle it through—at least I could rationalize it yesterday. But it is ugly to read, hence ugly to maintain. At first glance what stands out is that some then() methods return values and one accepts a value returned from the previous future. It is not clear why—at least not without noodling. And all the while that noodling is taking place, I would not be thinking about the actual business value of the code, which resided in the ProxyCar object which is manipulating a real car in another isolate.

So, as the esteemed Kasper Lund suggested (challenged? cajoled?) in last night's comments, I ought to make use of Dart's async / await functions.

I start by marking the main entry point of my script as async:
main() async {
  // ...
}
As the name suggests, this indicates that the code inside is asynchronous. More specifically, it says that some code will return futures—futures that would otherwise need to be chained to ensure that they run in the expected order. The first future is returned from the isolate spawned to perform independent, real car work. Above, I waited for it to be ready with a then(). Now I can await it:
main() async {
  var r = new ReceivePort();
  await Isolate.spawn(other, r.sendPort);
  // ...
}
Since this main() function is marked async no other code in here will run until Isolate.spawn()'s future completes. Exactly as with the then(), but without the mess.

Next up is one of the mysterious return value futures. Previously, I waited for the first message to come back from the isolate with then((_) => receiveStream.first). That first message was the isolate sending a SendPort back to the main() execution worker so that code in main() can send messages back to the isolate. The hash-rocket return value returns the message so that the next future completes with its value.

Thus, the following two lines get a SendPort from the isolate to enable communication into the isolate and gives it to the ProxyCar:
    // ...
    then((_) => receiveStream.first).
    then((s) { car = new ProxyCar(receiveStream, s); }).
    // ...
This is hard to explain. It is hard to read. It is going to cause problems as the code evolves.

All I want is a SendPort from the isolate. With await, this is written:
  SendPort s = await receiveStream.first;
Once the value is ready, assign it to the local s variable. Easy-peasy! Then on the next line I create my proxy car just as if this were procedural code:
  car = new ProxyCar(receiveStream, s);
That is much easier to read.

I can then drive my car (which proxies a drive request to the real car in its isolated worker environment):
  car.drive();
No awaiting is needed for either of these as I am just sending messages. The only reason it was needed in the future heap was because everything else was in that mess. Thanks to async and await, that mess is gone.

Things are not completely rosy, however. Even await is not going to convert that drive() method into a synchronous call. The interface implemented by both the real Car and the ProxyCar expects drive() to return void:
abstract class Automobile {
  String get state;
  void drive();
  void stop();
}
So the drive() is going to send a message, then allow execution to continue right on to the next statement without waiting for the real car to start driving or to update the proxy car's state. Printing the car's state right away would result in believing the car is stopped:
  car.drive();
  print("Car is ${car.state}");
  // State hasn't had a chance to update and would report "idle"
With the current interface, I cannot await drive()—I need a Future. So, temporarily, I reach under the ProxyCar covers and await a message (a state update from the real car) to its receiveStream:
  car.drive();
  await receiveStream.first;

  // Proxy car state is ready, so print
  print("Car is ${car.state}");
As I mentioned earlier, I will pick back up tomorrow converting the proxied interface into an asynchronous version of the current synchronous interface. For now I note that, even with the reaching-under-the-covers (which I was doing in the future-heap code anyway), my remote proxy code is already far more readable:
main() async {
  var r = new ReceivePort();
  var receiveStream = r.asBroadcastStream();

  await Isolate.spawn(other, r.sendPort);

  SendPort s = await receiveStream.first;

  ProxyCar car = new ProxyCar(receiveStream, s);

  car.drive();
  await receiveStream.first;

  print("Car is ${car.state}");

  car.stop();
  await receiveStream.first;

  print("Car is ${await car.state}");
}
That lovely win makes for a fine stopping point tonight. More async adapters tomorrow!


Day #62

Monday, January 11, 2016

Remote Proxy Pattern and Dart Isolates


It seemed like a good idea at the time.

I would like to experiment with remote proxy implementations of the proxy pattern in Dart. You know what might work for that? Dart isolates. Well, probably not, but it seems like a good idea...

I start by simplifying the Car class, which will serve as the real subject in the pattern, to just an automobile that can drive, stop, and report state:
// Real Subject
class Car implements Automobile {
  String state = 'idle';
  void drive() { state = 'driving'; }
  void stop()  { state = 'idle'; }
}
The proxy subject will then be tasked with communicating with the real subject across isolates. I am unsure exactly how that is going to work, but the proxy subject will need a SendPort, at the very least, to request the real car update itself. So I start with:
// Proxy Subject
class ProxyCar implements Automobile {
  SendPort _s;
  String _state = "???";

  String get state => _state;
  void drive() { _s.send(#drive); }
  void stop() { _s.send(#stop); }
}
Where the SendPort comes from and how the _state private instance variable gets updated are questions that I will try to answer in a bit.

First, I want to establish the other isolate to which the main thread will talk. Like all isolates, I need to accept a SendPort through which it can send information back to the main thread. And I am pretty sure that I need for the main thread to be able to send information to the isolate, so the first thing I do is create a ReceivePort that I can send back:
other(SendPort s) {
  var r = new ReceivePort();
  s.send(r.sendPort);

  // Will establish real car here...
}
OK, back in the main thread, I do the usual isolate dance. I create a ReceivePort so that I can sent its sendPort property into the spawned other() isolate:
main() {
  ProxyCar car;

  var r = new ReceivePort();

  Isolate.
    spawn(other, r.sendPort).

    // Wait for isolate to be ready, then return first message, which is send
    // port back to the isolate
    then((_) => r.first).

    // Create proxy car with receive stream and isolate send port
    then((s) { /** Create proxy car here... **/ }).

    // Will drive and report state here...
}
After spawning the isolate, I wait for the returned Future to complete, indicating that the isolate is ready. Then, I return the first message sent back from other(), which is the SendPort through which I can send messages from main() to other().

Here, I note a problem. If I read the first property, then the receive port's stream is closed. That will cause problems as the ProxyCar tries to receive messages from the receive port. So instead, I convert the ReceivePort to a broadcast stream:
main() {
  ProxyCar car;

  var r = new ReceivePort();
  var receiveStream = r.asBroadcastStream();

  Isolate.
    spawn(other, r.sendPort).

    // Wait for isolate to be ready, then return first message, which is send
    // port back to the isolate
    then((_) => receiveStream.first).

    // Create proxy car with receive stream and isolate send port
    then((s) { car = new ProxyCar(receiveStream, s); }).

    // Will drive and report state here...
}
With that, I think I see a first pass implementation for the proxy car—it needs a stream on which to listen for messages from the real car and a send port through which messages can be sent to the real car. Something like this should work:
// Proxy Subject
class ProxyCar implements Automobile {
  SendPort _s;
  var _r;
  String _state = "???";

  ProxyCar(this._r, this._s) {
    _r.listen((message) {
      print("[ProxyCar] $message");
      _state = message;
    });
  }
  // state, drive, stop declared already...
}
The only messages that will come through that ReceivePort stream will (for now) be state updates, so I assign them to the _state instance variable. The rest is already in place—the already declared state, stop(), and start() methods will send messages through the SendPort supplied to the constructor.

So the rest of the main thread becomes:
  Isolate.
    spawn(other, r.sendPort).

    // Wait for isolate to be ready, then return first message, which is send
    // port back to the isolate
    then((_) => receiveStream.first).

    // Create proxy car with receive stream and isolate send port
    then((s) { car = new ProxyCar(receiveStream, s); }).

    // Drive proxy car, then wait for state message
    then((_) { car.drive(); }).
    then((_) => receiveStream.first).

    // Proxy car state is ready, so print
    then((_) { print("Car is ${car.state}"); }).

    // Stop proxy car, then wait for state message
    then((_) { car.stop(); }).
    then((_) => receiveStream.first).

    // Proxy car state is ready, so print
    then((_) { print("Car is ${car.state}"); });
Last, I need the real subject to work with the opposite send and receive ports. I will follow the same constructor signature, even though a broadcast stream is not necessary in the other isolate. That will make the creation of the real car look like:
other(SendPort s) {
  var r = new ReceivePort();
  s.send(r.sendPort);

  var receiveStream = r.asBroadcastStream();
  new Car(receiveStream, s);
}
And the real class needs to establish a listener for drive and stop messages from the proxy:
class Car implements Automobile {
  SendPort _s;
  var _r;
  Car(this._r, this._s) {
    _r.listen((message) {
      print(message);
      if (message == #drive) drive();
      if (message == #stop)  stop();
      _s.send(state);
    });
  }

  String state = 'idle';
  void drive() { state = 'driving'; }
  void stop()  { state = 'idle'; }
}
Phew! That was a lot harder than I expected. There is almost certainly some cleanup that I can perform. Perhaps the car classes can create their own ReceivePort instances. A little Future improvement is in order. Still, the code works:
$ ./bin/drive.dart                        
Symbol("drive")
[ProxyCar] driving
Car is driving
Symbol("stop")
[ProxyCar] idle
Car is idle
The real subject receives the #drive symbol. Then the proxy subject receives a message that the real subject is driving. Then the output of the current state from the proxy is that the car is driving.

I suppose I should have known that isolate code would get messy like this. Hopefully I can clean it up tomorrow.


Day #61

Sunday, January 10, 2016

Dart doesNotUnderstand Proxies


Patterns can be kinda dull. Consequences and implementations are pretty damn fun.

I got the proxy pattern working in Dart last night without much trouble. Let's see if I can cause trouble with the second implementation (a.k.a. doesNotUnderstand) from the Gang of Four book chapter on the pattern. The doesNotUnderstand method is a Smalltalk construct, but I think Dart's noSuchMethod ought to serve a similar purpose.

The Gang of Four's doesNotUnderstand implementation was framed as a generic solution. I am going to keep mine somewhat generic. I continue to use last night's protection proxy example for driving automobiles. The protection came in the form of preventing underage drivers from getting behind the wheel:
// Proxy Subject
class ProxyCar implements Automobile {
  // ...
  void drive() {
    if (_driver.age <= 16) {
      print("Sorry, the driver is too young to drive.");
      return;
    }

    _car.drive();
  }
}
Instead of protection solely in the drive() method, I am going to switch to a noSuchMethod() implementation. This protection proxy follows standard proxy practices in that it does not create an instance of the real subject (the car) until it is needed. The car getter method returns the private _car instance if it has been defined, otherwise it creates and assigns it:
class ProxyCar implements Automobile {
  Driver driver;
  Car _car;

  ProxyCar(this.driver);

  Car get car => _car ??= new Car();
  // noSuchMethod will go here...
}
To make the noSuchMethod() approach work, I am going to need to invoke arbitrary methods on the real subject. That means that I need to import dart:mirrors:
import 'dart:mirrors';
I next need to delete the existing drive() method. Once gone, invoking the drive() method on ProxyCar will send the call to noSuchMethod(). If the noSuchMethod() method is not defined in ProxyCar, then the call gets sent to the noSuchMethod() in ProxyCar's superclass, Object. Object's noSuchMethod() throws a NoSuchMethodError, which I do not want, so I declare noSuchMethod() in ProxyCar. With dart:mirrors, I can reflect on the car, then send the message and arguments that reached noSuchMethod() to the car instance:
class ProxyCar implements Automobile {
  // ...
  dynamic noSuchMethod(i) {
    if (driver.age <= 16)
      throw new IllegalDriverException(driver, "too young");

    return reflect(car).invoke(i.memberName, i.positionalArguments);
  }
}
I have switched to an exception here to really ensure that this registers as something wrong. With that, my client code is once again working. I create a 25 year-old driver, then send the drive() message to the proxy car:
  // Proxy will allow access to real subject
  print("* 25 year-old driver here:");
  car = new ProxyCar(new Driver(25));
  car.drive();
Since drive() is not defined on ProxyCar, it gets sent to noSuchMethod(), which checks that the driver's age is greater than 16, then tells the car to drive:
$ ./bin/drive.dart
* 25 year-old driver here:
Car has been driven!
If a 16 year-old tries to get behind the wheel, the noSuchMethod() guard clause kicks in, giving me the appropriate exception:
$ ./bin/drive.dart
* 16 year-old driver here:
Unhandled exception:
IllegalDriverException: 16 year old driver is too young!
I can add other gaurd clauses to noSuchMethod() as well. For example, I can guard against the same conditions as in the Gang of Four example—illegal messages:
class ProxyCar implements Automobile {
  // ...
  dynamic noSuchMethod(i) {
    if (i.memberName != #drive)
      throw new IllegalAutomobileActionException(i.memberName);
    if (driver.age <= 16)
      throw new IllegalDriverException(driver, "too young");

    return reflect(car).invoke(i.memberName, i.positionalArguments);
  }
}
Now if the driver tries to do something wrong with the car, an exception will arise regardless of age:
  print("* 25 year-old driver here:");
  car = new ProxyCar(new Driver(25));
  car.fly();
  // ==> IllegalAutomobileActionException: Symbol("fly")
The Gang of Four makes this completely generic, but I am hard pressed to think of a situation in which I could define a list of valid methods that would not apply to a single interface (like Automobile in this case). Regardless, this noSuchMethod() proxy approach works quite nicely—I think I will be using this in the future.

Play with the code on DartPad: https://dartpad.dartlang.org/c919e79c50e968cd314d.

Day #60

Saturday, January 9, 2016

A Simple Proxy Pattern in Dart


I start my exploration of the proxy pattern tonight by looking at the protection version of the pattern. I rather like the simplicity of the example used on the Wikipedia page, so I start there, adapting the code to Dart.

The subject of this example is an Automobile which can be driven:
// Subject
abstract class Automobile {
  void drive();
}
The proxy and real subjects will implement this (simple) interface. The real subject, a Car, includes possibly scary business logic that should be kept out of irresponsible hands:
// Real Subject
class Car implements Automobile {
  void drive() {
    print("Car has been driven!");
  }
}
The proxy subject is where the action takes place. The constructor requires a Driver, which will be used to determine of the real subject needs protection:
// Proxy Subject
class ProxyCar implements Automobile {
  Driver _driver;
  Car _car;

  ProxyCar(this._driver) {
    _car = new Car();
  }
  // ...
}
In addition to storing the driver, the constructor also creates an instance of the real subject. Neither the driver nor the real subject need to be accessed from outside the class, so both are declared private.

Last up, I implement the drive() from the Automobile interface. If the driver is too young, then access is denied, otherwise the drive() method on the real subject is invoked:
// Proxy Subject
class ProxyCar implements Automobile {
  // ...
  void drive() {
    if (_driver.age <= 16) {
      print("Sorry, the driver is too young to drive.");
      return;
    }

    _car.drive();
  }
}
And that is all there is to the protection proxy. Client code can create an instance of the ProxyCar for an underage driver and a proper age drive, trying to drive both:
  Automobile car;

  // Proxy will deny access to real subject
  print("* 16 year-old drive here:");
  car = new ProxyCar(new Driver(16));
  car.drive();
  print('');

  // Proxy will allow access to real subject
  print("* 25 year-old drive here:");
  car = new ProxyCar(new Driver(25));
  car.drive();
  print('');
With that, one car is prevented from being driven while the other works fine:
$ ./bin/drive.dart
* 16 year-old drive here:
Sorry, the driver is too young to drive.

* 25 year-old drive here:
Car has been driven!
And there you go, a simple protection proxy pattern implementation in a few lines of Dart.

Play with the code on DartPad: https://dartpad.dartlang.org/43ea1a7ec5c1684452fc.

Day #59