This is just a jotting down of thoughts I have been having for the last couple of weeks. Had an interesting discussion with Pandu on this last evening and I thought it would be valuable writing down some of the key takeaways. Most of this is early thinking, but I think that as programmers, all of us need to start thinking hard about the issues below and start figuring our way around them.
1) Learn the trade-offs all over again: The CPU is getting cheaper and would continue to do so at an ever increasing pace as transistor density continues to increase. However, while disk capacity is getting cheaper and would continue to do so, disk IO is not getting any faster. While IO has always been the big bottleneck , with CPUs getting more powerful, more and more workloads would become IO bound. Thankfully Flash provides some reprieve here and as hybrid disks and pure Flash storage gets mainstream, IO contention should reduce. But to take advantage of Flash, we would need to design apps which are Flash aware so that you can keep the hotter areas of your data on the Flash storage while the colder ones go on magnetic storage. A much harder problem is the memory wall - the access to memory is not getting faster and as CPUs get more powerful, all that computing power would end up waiting on memory. There are no hardware solutions to this, so it boils down to better caching and being super aware of data locality. So when you design a app next time, think about the trade offs all over again - CPU is cheap, code needs to be Flash aware and design for better caching and locality.
2) Learn to Parallelize Code: I have written and talked about multi-core several times, and it always surprises me to see people getting surprised when they learn that their apps would need to be re-written to take advantage of the next set of chips. All that cheap computing power in the previous point is not easy to harness because it would be distributed across multiple cores. To take advantage of these cores, your code would need to be parallelized. This needs to happen on both client side and server side:
a) Server-Side: While server-side workloads are mostly parallelized already thanks to the transaction model on databases for stateful workloads and the atomic request-reply model in the web-server stateless model, we do have a problem is on the business logic code. As your web-server hands over a request to a business logic component and it does its computation, there are other requests waiting to be serviced by the same business logic component even as a CPU core lies idle.
b) On the client, the situation is worse - all UI is done using one thread. And while some apps use the background worker thread approach, even there most of the apps tend to use a single thread only. Now on the client again, the CPU is not getting any faster, but more and more slow ones are becoming available. So for your app to take advantage of the new hardware, it needs to be parallelized.
So irrespective of whether you are on the server or the client, you need to re-write your code. I had posted on some of what you can do earlier over here. Since then, Microsoft has launched a full fledged Parallel Computing Developer Center which is a great resource to learn the issues and how to address them.
3) Learn to Work with Offline Data: While bandwidth cost is getting cheaper and coverage is increasing, the fact is that it is flaky - sometimes you have a lot of it, sometime you have none at all. Also, there are other points of failure in the system and there is no chance that you would have the latest, correct data all the time. This has two consequences:
a) From a client side perspective, since the expectation is that with pervasive connectivity, you can be online anytime, connected apps is the way to go. However, the flakiness also means that you need to work offline. That means storing data locally and sync-ing it with the online service depending on bandwidth availability. This would at times lead to issues - the pricelist on the tablet PC of the sales guy may change while he makes a transaction based on the data he has. Offline data is not friendly towards consistency, but availability. And a business would rather make a system more available, even if it means that sometimes business transactions would happen on wrong data which would require compensating actions.
b) From a server perspective, since your app and data would be residing in the Cloud, spread over several boxes, maybe several datacenters, changes to data would happen in different places at different points in time by different activities. So the change in inventory for example would need to be propagated and since bandwidth is flaky and boxes would go down, you would need to take the decision on the current inventory level based on the data that you have, and not some global version of the inventory. At some point in time, the data would sync and it would be figured that some transactions happened on bad data and these would need to be compensated again.
This model of working with data you have (I am calling this offline data for the want of a better word) in an optimistic way hoping that the data is correct, syncing at some later time in point, figuring out the inconsistencies and then dealing with them is increasingly going to be a complex problem all App architects would have to solve. While there is some technology to help - ADO.net Sync Framework, Workflow Foundation and Communication Foundation come to mind - the business logic of detection, deciding on the compensation and carrying out the compensation would need to be designed in the biz-logic of the app.
4) Learn to Slice up the App: The point on data above leads to a bigger point on slicing up the app in general. The first level of slicing is on having an offline semi-connected client. The second level of slicing is on the server-side. Some of the server-side functionality would need to be in the Enterprise datacenter where your app may need to talk to some of the other systems. Some of the functionality would need to go to the Cloud - mostly areas where you need infinite scaling and 100% uptime. This leads to questions on what should be the boundaries, how do you come up with the boundaries, how does the communication happen between the boundaries, etc. So how we slice up the apps is a huge issue, and we all need to find our feet when it comes to this. I have some thoughts on this, but over here I basically want to highlight the issue and not discuss possible approaches - that is a topic for some other post in future.
So those were the major points in my mind on the challenges ahead and skills we would need to acquire to address these challenges. Obviously, various technologies would also evolve to help solve these issues - new languages, new algorithms, new frameworks, new design patterns .. I think the way to go would be declarative - state your intent and let the runtimes handle stuff for you. Also it would be mostly model-led. Lots of new stuff to learn - it never gets too dull here!
0 comments:
Post a Comment