10,000 Foot View
The FatFractal Platform is an end-to-end solution for developing cloud-based apps for any connected device. Design goals for the Platform include efficiency across the board, lowest cost and ease-of-use. This section provides an overview of the FatFractal Platform’s Backend Architecture.
The hands-on interface for developers who are building apps is mostly at the SDK level, but we think building a cloud-based app means understanding the underlying services (and having access to them!) beyond clientside SDKs.
We built our own middleware layer to prevent clientside and serverside lock-in, to allow open source development of platform services and modules and to ensure abstraction, at every level (IaaS, PaaS, Services and so on), that benefit the developer.
Platform Architecture Fundamentals:
- All Platform Backend components are implemented in Java, supported everywhere, and have a single dependency: the JVM.
- Most serverside, programming languages intended for backend “business” logic are implemented in Java.
- The FatFractal Platform can run on virtualized machines (VMs) or native OS’s, so long as the JVM is available.
- The FatFractal Platform can be deployed to one server or to a cluster of servers.
- The FatFractal Platform components all communicate via a light-weight service bus, generating a fabric.
Should developers care about the middleware solution they are using? We think so.
To create the most compelling apps you can, with the best performance and scaling, the least serverside configuration and maintenance issues, you have to know about the end-to-end architecture.
It can’t be a black box on your platform’s backend.
Platform Architecture: a View from the Backend
At a high level, the Platform doesn’t have many moving parts. The parts it does have are kept small, single-purpose and scalable.
- FatFractal Router (“Director”): the gateway to the FatFractal fabric. Its primary responsibility is to route HTTP(S) requests to the proper application engines.
- FatFractal Module Repository: responsible for maintaining all versions of all modules and providing access to them by application engines. Modules are mostly associated with “framework (i.e., NoServer, Rails) and language stacks” and are fetched dynamically by application engines based on applications requirements. Modules are identified by an artifact identifier and version number. This allows for versioning support where older applications that will not be re-factored can still get access to legacy modules.
- FatFractal Deployer: The deployer is the only FatFractal component that communicates directly to the desktop environment. When developers install the desktop runtime environment they must provide credentials which are authenticated by the Platform. The response is a credential file which is placed into the runtime footprint. When the command line is used to deploy an application to the cloud, it propagates the credential file along with the application. The deployer validates the credential file and if all is good allows the deployment to continue.
- FatFractal Infrastructure Services: All access to infrastructure resources (e.g. storage) is abstracted by services (e.g. the DataStore service) so that the FatFractal Platform can remain agnostic as to the underlying infrastructure (e.g. Amazon EC2).
- Application Services: FatFractal has a services-based architecture throughout. Application services are lightweight and JSON-based (although they are not limited to JSON). We provide a variety of services “out-of-the-box,” such as location, payment, email and geolocation. We will also allow developers to publish and subscribe to services more broadly, as we open up the services interface.
Develop Locally and Deploy to the Cloud with 100% Fidelity
Building an app happens locally and we like it that way. Why should you have to configure or test or even deploy to the cloud until you’re ready? We believe a desktop runtime environment is required, particularly for iterative creation and testing of apps. Personally, we don’t want to be tethered to the network during the find-fix-deploy-log-retry process.
With some platforms, you don’t have that option, or if you do, it’s likely a simulation runtime that will require reconfiguration when you deploy to the cloud. The FatFractal Engine, in contrast, is identical whether on the desktop or running in the cloud. That means you get consistent application behavior, when you’re hitting the datastore, services, language modules or anything else your app uses.
When you’re ready, FatFractal provides both command line and “push button” deployment to the cloud.
Deploying to the cloud post-development is a single step process: so if you like to go back and forth all the time, feel free.
The desktop environment is covered in some depth in the documentation.
Console: Application usage information, administration of domains and more are facilitated through utility-grade instrumentation.
Data Browser: Browse and edit collections, objects, including their metadata, by application. Can be useful for quick fixes or easy changes to backend data both during the local development/deployment process and after you deploy to the cloud.
Deployment Controller: Communicates with the local Engine as well as the FatFractal Platform in the cloud, responsible for authentication, among other things.
Reference Manager: Allows for smart management of indirect references to optimize clientside performance.
Local Runtime Data Cache: Optimizes fetching and processing data from the backend, based on developer’s requirements.
Serializer/Deserializer: Translates objects from your clientside language (native object models, not just dictionaries and hashmaps!) to the system’s backend data models. And vice versa.
The Engine is the Heart of the Platform
Most Platform as a Service (PaaS) vendors support cloud-based apps by virtualizing preconfigured virtual machines (VMs). FatFractal approaches the problem differently: FatFractal Engines (FFE) run on everything. FatFractal Engines run in everything. Everything runs on FatFractal Engines. It’s a fabric.
The FFE is a specialized middleware container that loads and runs applications on top of cloud infrastructure, with the highest-possible efficiency (smallest footprint, lowest cost):
- FFE supports a pluggable, module architecture that allows encapsulated framework containers (specialized “stacks”) to be dynamically loaded and unloaded via the Deployer based on application requirements.
- FFE estimates application requirements to create compute capacity models as applications are deployed to engines.
- FFE may have thousands of applications tenanted but will only dedicate compute resources (specifically memory) to those that are active.
- FFE uses heuristics, combined with application usage patterns, to optimize usage of infrastructure services, minimizing the cost associated with hosted apps.
Since the FatFractal Engine self-configures, based on an application’s requirements, it can be incredibly small and scale wicked-fast. The developer doesn’t have to pay attention to the app’s requirements, per se: the Platform’s top goal is to optimize, at every point, both efficiency and cost.
We are in development to provide coders with explicit hooks to orchestrate such application priorities as: a) I want performance on the clientside to be fastest-possible so locate me closer geographically, regardless of cost; or b) I want my backend on the lowest cost infrastructure possible, regardless of performance; or c) I want to use a CDN located at “this place” to offload all BLOBs and so on.
The NoServer™ Module
The NoServer Module encapsulates all the services needed to support the FatFractal SDKs. There is a lot of functionality in NoServer, covered by the Documentation and Reference sections. Most of what the industry has started calling “Backend-as-a-Service” is managed by this module.
Because NoServer is part of the larger FatFractal Platform, crucial aspects of ensuring an application’s performance and management are handled by other, independent, separately-scalable platform services, many of which are automated to drive lowest cost on any infrastructure.
The complete set of information describing the developer’s application and the object model for the application is transmitted to the NoServer Module. The clientside code, including the JSON-encapsulated object model for the application, will be authenticated and routed as appropriate: 1) the JSON-encapsulated object model will be deserialized and configured for the app’s backend; 2) the application.ffdl configuration information is processes before the application starts up; 3) request URIs will be parsed; 4) client code will be routed to the script execution engine; and 5) serverside code will go to the applicable services and modules.
At this point, the persistence and management of the object model depends on:
a) the defaults, commands and configurations contained in application.ffdl and viewable as metadata as “the Backend State Representation;”
b) the instructions in the client code, as interpreted by the Script Execution Engine;
c) the processing of the object model to optimize the representation and manipulation of the datagraph; and
d) a CRUD Engine’s management of rest encryption/decryption, validation, the processing and handling of events, the handling of permission policies on objects and the parsing and execution of queries and updates.
Among other things, the result of all this processing is an optimized set of data structures that can be persisted via a datastore abstraction API. The datastore abstraction API directs the data to any supported data storage technology. FatFractal persists data solely through the DataStore service and leverages several different storage technologies, NoSQL and RDBMS, for example. Since persistence is abstracted storage technologies can be added and swapped out as necessary.
The FatFractal Ruby Module in also beta and supports both scripting and Rails 3.+ applications. Ruby is the first of several JVM-enabled languages that will be available on the FatFractal Platform.
The Ruby Module leverages the JRuby embed interface, specifically it orchestrates the execution of multiple script engines. When an application is registered with the Ruby module it is assigned to a script engine. As requests are delegated to the Ruby module, it directs them to the appropriate script engine. Once a request has been assigned to a script engine, it is queued for execution by a backing thread pool.
Ruby applications are only limited by what the JRuby embed interface supports. Going forward, FatFractal will also provide its own Ruby-encapsulated services, giving developers broader access to FatFractal platform services.