Wednesday, September 30, 2009

Thoughts on Beautiful Architecture ch. 11 - GNU Emacs: Creeping Featurism Is a Strength

Being a long-time Emacs user, I am very impressed with its extendability and mutability. Almost everyone I know who uses Emacs has his or her Emacs set up in an unique way that suits one's own needs and style. The funny thing is that there are actually not too many people who are truly proficient in Lisp; however most people still can pick up some Emacs Lisp excerpts and just by reading the comments on them modify and incorporate the code pieces into their own environment. This shows the ease of extendability. Other systems like Eclipse have a steeper learning curve.

Not only is it easy to extend and customize, the good thing about Emacs is that in incorporating new changes even if some errors are introduced to one's own emacs.el file, the basic Emacs almost always still comes up. Thus one is able to go through the Emacs's Messages buffer and gather information on the errors. This gives people the assurance to try new things. In contrast, this is usually not true for other highly extendable systems.

Although I have been using Emacs for a long time, however I have never read a paper discussing its architecture. I see this chapter is able to explain it in a high level basically in one diagram and a few pages. This shows the core Emacs's simplicity; any bell and whistle is added an extension. This is how an application ought to be to satisfy a broad and diverse user pool. This model also supports piecemeal growth and it actually has an Agile-programming philosophy to it. "Necessity is the father of creation", if someone needs something, he or she will build an extension. The power of Emacs to incorporate new packages makes it easy to leverage on other people's creations.

Tuesday, September 29, 2009

Thoughts on Our Pattern Language

Our Pattern Language (OPL) is a pattern language that focuses on the design of parallel software. It is concerned with software architecture and ways to design and implement parallel algorithms. The required reading for my class is essentially an introduction paper on OPL. Here in the paper it breaks parallel systems into five layers with the first two side-by-side; it then lists out the patterns belonging to each of these five layers: architecture, computation, parallel algorithm strategy, implementation strategy, and concurrent execution.

The paper starts out by listing the four typical types of programmers. I agree with the authors that there is quite a difference between them. From my own experience I could easily discern the differences between application programmers and what I called system programmers (where the paper calls them the platform programmers). For one thing, system programmers need to take into account of hardware capabilities; they know the hardware is not perfect and it needs to work with clever software in fulfilling various requirements such as performance and scalability. On the other hand, most of the application programmers can work with the view of an ideal machine and get by with that. The paper also supports my view as well as it suggests that the application programmers are mostly domain experts who in the context of paper may not know much about parallel programming; this is fine since most of it is abstracted out from them and instead is supported by the framework or platform underneath.

If so, then I am not sure whether the top two layers are necessary for OPL. Granted that whatever implemented in the application domain needs to hook to the parallel framework below to achieve parallelism. However, taking a look at the top-layer patterns they do not seem parallel-system-specific. In fact, most of them are well known patterns that is used in all sorts of systems. In a way, this shows the success of the layers down below in supporting various architecture at top. If one then tries to document all the different architectural and computational patterns possible on a parallel system, won't it make the language top-heavy and out-of-focus? Perhaps it should just concentrate on the lower three layers where there is direct contact with parallelism.

Sunday, September 27, 2009

Thoughts on Beautiful Architecture ch. 10 - The Strength of Metacircular Virtual Machines: Jikes RVM

In this chapter Ian Rogers and Dave Grove described a metacircular runtime environment for Java - Jikes RVM. The authors made a convincing point - a program language should allow enough expression that itself can be written in its own language. Just like the C compiler writers usually are the ones that know C the best, same applies to Java VM implementers. Writing the runtime environment in Java gives the language experts a chance to test out the language and to identify any shortcomings.

One recurring architectural decision throughout the chapter has to do with cost of optimization vs. its potential performance gain such as the use of basic compiler vs. optimizing compiler that is more costly and requires more system resource. Taking a step back, even the runtime analysis itself requires resources, although the authors do point out these requirement are modest; on the other hand, I would image the cost also depends on the amount and frequency of the analysis. This gets me thinking whether one would need to take into account of the performance of the underlying hardware to set the VM behavior. Could different decisions be the best under different hardware setup, such as when the VM runs in a high-performance server vs. a low-speed PC?

Thursday, September 24, 2009

Thoughts on The Adaptive Object-Model Architectural Style

After reading the high-level description of the adaptive object-model architecture I think it is brilliant. Instead of implementing classes that correspond to the different business entities, in contrast this style is based on user defining descriptions of structures and rules within that particular business domain thus making it very flexible to changes in business rules. In the last lecture Professor Johnson was asking the class about what kinds of architecture could last a long time; with its advantages of adaptability and quick turnaround, applications done in this architectural style should last much longer than the traditional object model in our ever-changing business world.

Since this style involves another level of abstraction, I can see it is harder for one to comprehend. It also depends on each person's past experience and the programming language he or she uses. For Smalltalk programmers it should be more familiar due to their exposure to metaclasses. Here I have a suggestion on section 3, Examples of Adaptive Object-Models, it could go add an example of type creation, it is hard to grasp the brilliance of the architecture just by reading the high-level description and looking at the UML diagram.

This architecture hinges on two key patterns: TypeObject and Property. I was unfamiliar with the former and thus I digged up a bit online. The link below points to another paper written by professor Johnson which clearly explains the pattern:

http://www.comlab.ox.ac.uk/people/jeremy.gibbons/dpa/typeobject.pdf

I also saw the term "framework" being used multiple times in this paper. Typically, a framework enables easy creation of multiple programs. Since in this architectural style new types can be created dynamically based on different user rules, thus each run of the application with a different rule set will produce a different set of object types; one could argue that they are different programs. I think that is why the examples in the paper are referred to as frameworks, which means that this architectural style also gives us a template for creating a framework.

Tuesday, September 22, 2009

Thoughts on JPC: An x86 PC Emulator in Pure Java

In this chapter Rhys Newman and Christopher Dennis went through the design of JPC, an x86 PC emulator in Java and gave tips on constructing an efficient large-scale Java program. At the end, the authors gave a recipe for constructing a beautiful architecture.

The authors first presented their case for an emulator instead of a VM. They argued that VMs need to always rely on some degree of hardware support. In contrast, an emulator, especially a Java-based emulator, can run on any architecture. As the x86 architecture becomes even more dominating (perhaps except at the space of small embedded environment such as cell phones), this may not be too advantageous. I think the user's choice between one and the other will come down to performance and security. No doubt that the Java VM, being one of the earliest large-scale VM deployment, has been proven to be reliable and secure. The authors' task now is to make it as efficient as possible.

I agree with the authors that emulating different pieces of hardware require different considerations as there is a gradient of complexity and execution time between the hardware components. It is the right tradeoff to focus on code clarify and modular design for simple and less used components and on the ultimate performance for CPU and memory. After all, according to Amdahl's law, when optimizing a component in an attempt to improve the overall system performance, one can only improve at most up to the time or resource that component takes.

To increase the perforamce of JPC, it is necessary for the authors to have a good understanding of JVM. From my own experience, when working on various hardware platforms, we also usually have the same approach. Typically, during the development time one knows about the initial platform family that the code will be deployed on and thus one writes code to take advantage of the characteristics of that hardware to capture performance gain. However, as hardware progresses and the new generations come out replacing the old ones, they may have different characteristics such as the cache line size and the numbers of registers. The special tricks used to enhance the performance no longer makes sense, sometimes even become harmful. Unfortunately there is simply no time to go back and rewrite the code, sometimes it is even hard to do when the code needs to be capable to run on both hardware. This usually goes unnoticed externally just because the new hardware often gives better performance and thus shadow the software's inefficiency; however still this means that the code is no longer taking advantage of the hardware features. Reading this chapter, I was thinking having a VM or an emulator in the middle may be the solution. As a new hardware comes out, now only the VM or the emulator needs to be optimized for the new hardware, the rest of the code running on top of them can take advantage of the new hardware indirectly.

At the end, the authors gave a game plan for implementing a beautiful architecture. It is interesting that they talk about having an end-to-end prototype at an early stage and at each stage focusing the testing on the whole prototype. This runs orthogonal to the usual division of labor that I've seen where the whole system is broken into modules and each module owner is responsible for perfecting his or her module until a final integration at the end. It seems that we will need to change habits and to integrate early and to integrate often.

Sunday, September 20, 2009

Thoughts on the Big Ball of Mud Pattern

Big Ball of Mud can be thought as anti-pattern. Code in the Big Ball of Mud style lacks a form needed to be classified to a pattern. However, it is so prevalent thus the authors here classify it as the pattern that lacks clear patterns. It is almost impossible to give a precise description but we all know when we see it. One way to tell whether an architecture is a big ball of mud is to attempt to describe it either in a short document or a graph. If it is not possible or if it comes with all sorts of exceptions, then yeah, it is a big ball of mud.

Brian Foote and Joseph Yoder also listed out the various forces that cause the Big Ball of Mud architecture. Being at a big company where one does not need to worry about survival all the time, my personal experience was that most of the projects actually started out with a good design. However, some of them eventually turned to a big ball of mud. Besides the forces such as changes in requirements that the authors had already described, another force that I have noticed was Confidence, or the lack of.

Extreme Programming advocates thorough and automatic unit testing as the enabler of continuous refactoring. However, especially in a large project development, this is not so simple. It is hard to have the absolute confidence that one's own UT suite can catch everything that can go wrong with a code change, let alone the UT suite created by someone else. When proposing changes in common code that are shared by multiple projects, it is understandable that the other teams would have concerns about the new changes especially when they don't need them. Therefore there is always a strong put to leave the original code alone and instead to duplicate it for the new use. Gradually the code base becomes bloated and the architecture starts to lose its form. Once a precedence is set, more exceptions will follow. Inevitably the architecture eventually becomes a ball of mud.

Another source of architectural form degradation is during performance tuning. As the phrase says, "make it work, make it right, make it fast", performance tuning often occurs at the end of development when one starts to realize that the system performance will not fulfill the requirement (typically at the end of the development is the time when one can actually measure the performance). Unfortunately, many times the architecture suffers such as the module boundaries are violated for better performance. The end result is that the architecture the developers have so meticulously tried to maintain now is deformed; eventually it becomes a ball of mud.

Thoughts on Beautiful Architecture ch. 8 - Guardian: A Fault-Tolerant OS Environment

In this chapter Greg Lehey described the architecture of Guardian - the OS for Tandem's "NonStop" series of computer and attempted to answer the question on why such a revolutionary architecture had so little impact.

The first thing that impressed me was its total hardware redundancy at its time. I have also worked on a couple of high availability systems with hardware redundancy myself in this decade. In the systems that I've worked on, in contrast the design is to have one single set of components on one board with high speed links between boards. This way the user can decide whether to pay the additional cost for redundancy. Thus, it actually makes sense to have a total duplication of hardware to prevent the cost associated with a second design. As for Tandem's case, its hardware architecture actually incorporates redundancy on the same board which may be less flexible. It is interesting that they did not take into account of the difference between the mean time between failure (MTBF) of the different components. For low-risk components such as IPB, one might avoid having a standby to cut down on the cost; especially from reading the chapter it seems the additional cost was one of the disadvantages when competing with its competitors.

Since many devices can only be directly accessible by only a couple of CPUs, the Tandem machine relies heavily on the messages exchanges between CPUs. The Tandem engineers later cleverly extended the message-passing mechanism beyond one box to support EXPAND and FOX. I am curious about the time difference between local IO access, in-box IO access, and remote IO access and I think the difference most likely is significant. In this case, it may be necessary for the OS to allocate the resources with locality in mind. I am not sure whether this is done in Guardian.

The author reserves his explanation on Tandem machine's lack of impact at the end. Since this was way before my time, I really don't know how open that companies at the seventies on documenting their architecture. I can't help to speculate perhaps since this is a proprietary machine, disclosing the architecture is therefore discouraged? Perhaps that is why it did not make a bigger splash?

Wednesday, September 16, 2009

Thoughts on the Layers pattern

The author describes the Layers pattern as the architectural pattern that can help in a situation when a complex application can be decomposed to subtasks at different levels of abstraction. It is a fine idea however the choice of using the network stack as its example makes it confusing.

For network stack, it makes sense only when there are two entities in communication. One major theme here is to provide an illusion that each layer of the stack is directly communicating with its corresponding layer of the other entity. What's more, each layer has its own data. What the upper layer sends down to the lower layer is usually considered opaque by the lower layer. It simply encapsulates the data as the payload with its header consisting the information this layer cares about. In contrast, judging from the other parts of the chapter, such behaviors are not necessary true nor is important in deploying the Layers pattern. It seems to me that for network stack, the upper layer exchanges data through the lower layers which simply serves as a delivery service; in contrast here in the Layers pattern, the upper layer uses the lower layer to transform its data.

Thus I believe what's more essential here is to have the ability to recursively break a complex task to simpler subtasks and to enforce clearly defined APIs between a task and its subtasks for isolation and exchangeability. If we define the pattern this ways, then programs containing clear boundaries between modules, having a consistent abstraction level throughout the body of their functions, plus always maneuvering the abstraction layers sequentially can be considered as practicing this architectural pattern.

Tuesday, September 15, 2009

Thoughts on Beautiful Architecture ch. 7 - Xen and the Beauty of Virtualization

I am now at the half way of this book. Since each chapter of the book is written by different authors, one can definitely feel the different styles the various authors used in describing the architecture of their systems. Even the depth can vary considerably from chapter to chapter. For example, this chapter addresses the architecture at a higher level than the previous Facebook chapter. Just like a couple of the previous chapters are written by authors favoring agile programming methodologies, this chapter heavily promotes the open source concept.

Derek Murray and Keir Fraser first gave the background on the Xen project. It is interesting in their description of the Xenoservers that they mentioned that there is mutual distrust between the customer and the provider. It seems to me that the use of Xen only solves this problem in one direction. I can see that Xen provides the provider (assuming to be the one running the hypervisor) protection from the customer but not the other way around. Professor Sam King et al. wrote a paper on malicious virtual-machine monitors (SubVirt: Implementing malware with virtual machines: https://agora.cs.illinois.edu/download/attachments/19924902/04_king06.pdf?version=1&modificationDate=1200454246000) which shows that it is very difficult for upper-layer software to detect malicious lower-layer software. In this case, the customer is running a guest OS on top, it will be difficult for him/her to detect a malicious hypervisor installed by the producer.

The idea of paravirtualization represents the tradeoff between performance and ease of use. Since the authors has listed performance as the first goal, such tradeoff makes sense. It is great that the hardware vendors have then caught on the virtualization trend and provided the right hardware support that software can leverage on to avoid such decision.

Sunday, September 13, 2009

Thoughts on Pipes and Filters pattern

Any UNIX user is no stranger to the Pipes and Filters pattern. In fact, I consider it a signature of UNIX for its ease in combing various utilities (filters) to create a final output by piping the output of one utility as an input of another. Since this pattern enables the intermediate filters to execute in parallel, as the prevalence of multi-core systems increase, I can see it gaining even higher popularity.

The author lists direct function calling as the most simplistic but yet flexibility-limiting piping scheme. One variation I have seen to preserve flexibility, especially for passive filters, is to have a meta structure listing the ordering of the filters. When one filter produces output, it simply relies on the main routine or a controller to deliver it to the next filter based on the meta structure. To support a different pipeline configuration, one only needs to edit the meta structure.

Another variation that I've seen with uniform-data-type pipelines is instead of setting up various pipelines based on the current configuration, there is a super pipeline consisting of all filters. Then, based on the current configuration, a filter can be turned ON or OFF. When it is OFF, it simply pass along the result to the next filter.

Thoughts on Beautiful Architecture ch. 6 - Data Grows Up: The Architecture of the Facebook Platform

Dave Fetterman did a fantastic job explaining the architecture of Facebook. Even for a Faceboot-ignorant person like me, after reading through the chapter I have now a fairly good understanding of its architecture. The diagrams throughout the chapter are very useful, they really help the readers to picture the overall design.

A couple of years ago I got a chance to sit alongside the CTO of a networking gear at a banquet. One thing I asked was regarding Content vs Delivery. He firmly told me that money was definitely at Disney not Comcast. The content is what the end users care for and thus the delivery model has to be content-centric. The equivalent comparison at the web is Data vs. Website Technology; thus the model needs to be data-centric.

The genius of Web 2.0 is to have it users voluntarily contribute data that are interesting to the groups. The company no longer needs to worry about the content, instead it can focus on the delivery. On top of that, Facebook is clever to eliminate the need of each individual sites to create its own social network; instead they get to rely on the networks at Facebook and even present their own content at the site. In return, Facebook becomes the hub of these web destinations.

A large portion of the chapter focuses on FQL and FBML. It is a good architectural decision to leverage the proven technologies instead of creating new ones from scratch. I originally had some concerns on the inappropriate intimacy caused by FQL - the needs of the other websites o know the Facebook-internal table formats, however these can just be logical views and thus do not need to reflect the actual implementation. So it should turn out to be OK.

As I said, I am not yet a Facebook-user and so I do not know the actual implementation and interface. However, I do get from the chapter that security is definitely an important consideration. Even though, I still have doubts on exposing data to the third-party. For example, it seems that an user can agree to export the email addresses of his or her friends to a third-party website. Do the friends have a say on this? In addition, what prevent the third-party from caching this info and either use it or sell it to others for other purposes? What's more, how can an user ensure that the third-party will remove the data once he revokes the permission on data export?

Wednesday, September 9, 2009

Thoughts on Beautiful Architecture ch. 5 - Resource-Oriented Architectures

This chapter differs from the chapters before in the sense that the author's major focus is on describing an architectural style instead of a particular project. To a person with very limited experience in web applications, I feel the brilliance of REST is in addressing data like documents. It has an Unix resonance to it (where data is addressed like files). Just as in Unix one can do "cat /proc/1234" to retrieve information on a particular process, here one can retrieve http://server/employee/1234" to get information on an employee. Through just a few HTTP operations, the syntax supports the various operations on the data effectively. What's even better here is that the HTTP protocol supports providing information on the physical representation of the returned data and thus a client can present it correctly.

The author also envisions that a server can determine the amount of data to return based on the role or permission of a client. This gets me thinking, can a client specify the amount of data it wants? This surely would save network resource. Instead of a client receiving the whole data and then has to filter out the interesting portions, the server can just skipping them. On the other hand, to support such functionality it may cause unnecessary intimacy between the client and the server (client now needs to know the "views" of data the server can provide).

Tuesday, September 8, 2009

Thoughts on ArchJava: Connecting Software Architecture to Implementation

Although the title of the paper was about connecting architecture with implementation, the authors cleverly narrowed down the scope to a manageable subarea: communication integrity. I believe this is the right approach for the first phase of a grand topic as interface between components are certainly important and they are more tangible and thus much easier to enforce automatically than other aspects as design guidelines.

Two problems immediately come into mind, since the approach ArchJava requires annotating the source code, could it be done on the existing or the leveraged code? The authors's experience suggested that this answer is yes, although it did require quite a bit of effort; on the positively side this provided a refactoring opportunity. Second, could it be easily adapted to other languages? For starters, a separate effort is needed to produce a compiler for that each language to recognize the new annotations. I'm also not sure whether it can map well to non-OO languages such as C.

Thursday, September 3, 2009

Thoughts on Beautiful Architecture ch. 3 - Architecting for Scale

The author pointed out a major trend in the processor technology that really becomes significant in this decade - the trend of going multicore. This trend can now be felt in pretty much any software niche. Personally, being in the embedded system space, my company has resisted the trend for quite a while until we could no longer pretend the other cores do not exist since no one is planning to make a faster uni-core chip!

Another point I got from this chapter is the human factor in the architecture selection. When choosing an architecture, should the architect consider the skill sets of his or her team? In this chapter, the architect is facing such dilemma. A highly parallel system would be the right way to go however the team lacks the expertise in parallel programming. Fortunately, the architect was able to cleverly design an architecture that mostly shields the parallelism from the developers. This makes a great compromise.

This hardware trend to go multicore will eventually push for more software systems to become parallel, however many software developers are still not comfortable with it. I would image such architecture that hides parallelism from the developers would gain popularity.