Architecting for the Cloud
After introducing the (apparently somewhat charged, judging from the comments) topic of moving application functionality to the cloud, and then looking at the steps of creating and implementing an ASP.NET Web API project, we’re now going to take a brief step back before looking at how we can effectively make use of the data provided by these web-services inside AutoCAD.
If you’re looking to assign blame (not that any is needed ;-), it’s Scott McFarlane’s fault we’re taking this brief backwards step: Scott raised the excellent point – which really needs addressing sooner rather than later in this series – that, aside from the technical issue of creating and hosting a web-service, it’s really important to start with the right architecture in terms of separating your application’s business logic from the AutoCAD-specific code. While it’s hard to give more than general pointers in this area – as applications vary greatly – we’ll at least look at the specific example we’re covering in this series: moving core F# algorithms to the cloud that will return data to be used to generate AutoCAD geometry.
Business logic separation
Scott has a great deal of experience in this process, and I’ve been lucky enough to hear him talk about the benefits of a clean separation between business logic and platform-specific code at AU, over the years. While the devil is clearly in the detail, we can (and feel free to jump in with comments, Scott et al. :-) boil the process down to separating core algorithms so that they don’t have a dependency on specific platform capabilities. For instance, you may have an algorithm that needs to create geometry inside AutoCAD, but you can either collect the data you need from the separated algorithm (which is almost a requirement if hosting on the cloud – more on this later) or implement some kind of call-back capability, so that your platform-centric code can be called as appropriate by the core algorithm.
AutoCAD itself is a pretty good example of a product that was gone through this process with respect to its own dependent platform(s): after having become a Windows-only product over the course of many releases, it took significant re-architecture to strip out AutoCAD’s Windows-specific code during the project known internally as “The Big Split”. We now have a clean codebase shared across Windows and Mac versions of AutoCAD with platform-specific modules for each.
Now I’m not specifically encouraging you to depend less on AutoCAD as a platform – why on earth would I do that? ;-) – but this approach should help you integrate more cleanly with future versions of AutoCAD along with other platforms that are important to your business.
It also has additional benefits, as Scott has highlighted: it certainly makes algorithms easier to unit-test (very important if you’re adopting Agile processes such as test-driven development) and, of course, to move to the cloud.
AutoCAD components in the cloud
You may want to use some core AutoCAD-related component on the server – such as RealDWG – but this will change the shape of your application and the work needed to implement it: if you’re able to live without having a product-specific dependency in your web-service implementation, you’ll ultimately benefit from greater flexibility.
That said, there are lots of good reasons for using RealDWG in the cloud. You clearly don’t want heavyweight files transferred between the client and server, if it can be avoided: as the cloud-based platforms available to us become more rich, I expect we’ll see more and more all being done up there. In the meantime it’s worth taking a measured approach to data transfer.
Let’s take our example web-service: we pass two arguments to it, as part of the URL (the radius of the outer circle/sphere and the “level” or number of recursion steps to take). So it’s very lightweight in that respect. We could have used RealDWG to create a DWG containing our data on the server – effectively using .DWG as the data transport – but that would have been overkill, even with the large number of entities we’re potentially talking about. Se we choose to return JSON with a reasonably small (although it could be made smaller by abbreviating the field names) footprint.
If you choose to go down the route of integrating RealDWG, I recommend this AU session from a good friend and colleague of mine – as well as an accomplished AU speaker – Albert Szilvasy:
While we’re on the subject, you might want to check out this more recent session of Albert’s:
Sadly neither of these sessions were recorded, but the material should be of interest, at the very least. Be warned: the latter session is a little more future-oriented, and doesn’t necessarily reflect product capability that is either available today or in development.
What F# brings to the table
Part of the reason I chose F# in the first place for this project was that I find functional programming encourages good architectural practice: it encourages programmers to generate “pure” functions that do not modify things like the drawing database directly (these are known as “side effects”), but that return data which can then be used to do so. So from the start I wanted a clear separation of my core algorithm (my business logic) from my AutoCAD-centric code. It was therefore relatively easy to take that code and move it behind a web-service, as the code didn’t work directly with AutoCAD APIs, at all.
The original code returns a list of tuples – a core F# data-type that many of you will know from LISP – which is super-handy for returning sets of similar-looking data when you don’t want the overhead of implementing types or classes. Unfortunately these look pretty ugly when returned via JSON, so I decided to map them to lists of a temporary type I created for both Circles and Spheres. This has the advantage of having named properties (rather than m_Item1 etc.), making the JSON output easier to work with.
A side note on optimising the web-service’s behaviour: as we’ve implemented them as “pure” functions, our algorithm will always return the same results for the same arguments. This means it lends itself to some kind of memoization, so that we simply remember the results for arguments that have been used before – which could probably be implemented via some kind of caching mechanism in our web-service. I didn’t go down this path, though: I’ll leave that as a possible future exercise, as it seems an interesting challenge.
OK, I think that’s where I’m going to leave it, for today. In the next post we will take a look at consuming JSON data inside AutoCAD – honest! :-)