This document is about the basic concept of cloud applications.
Before you continue with this document you should have an account and create a cloud application as described here.
A cloud application is more or less a sandboxed OS X application. Basically you can do everything inside a cloud application you could do inside a sandboxed OS X application.
The cloud application holds some global properties common to all services. These are important for administration and at runtime:
//appName.obcl.io
). The name is unique to all cloud applications of all accounts and will be reserved for a while even you remove the application or your account.When you create a cloud application as described here, some things happens behind the scene:
A cloud application contains its services.
There are two types of services: invocation-based and request-based.
Request-based services are a kind of rawer: They response to a HTTP request. You define a Objective-C block as handler (C) and a predicate with a HTTP method (A) and a path (B) as matching rule:
[self handleRequestsWithMethod:@"GET" // A
matchingPath:@"/sayhelloto" // B
withBlock: // C
^(OCFRequest *request)
{
[request respondWith:[NSString stringWithFormat:@"Hello %@", request.parameters[@"name"]]);
}];
}
To such a service you can send a GET request as greeter.obcl.io/sayhello?name=Objective-Cloud
and will receive the respond Hello Objective-Cloud
.
We added methods to make receiving parameters and sending responses as easy as it could be.
To get more informations about request-based services refers to their documentation.
We built invocation-based services on top of request-based services. As usual you put your code in methods belonging to classes. The class name builds the path of the URL. The process of addressing the code, transferring arguments and returning values is transparent to the service.
+ (NSString *)sayHelloTo:(NSString*)name
return [NSString stringWithFormat:@"Hello %@", name]);
}
To get more informations about invocation-based services refers to their documentation.
Having the option to choose one of two service types leads to the question, which one to use. First of all: You can do everything with both services: You could write your own dispatcher in a request-based service, you have complete access to the HTTP request and response in an invocation-based service. So the correct question is: "What is more convenient to you?" And the answer depends of your service, especially on the API.
Let's have an example: You plan to write a service, that publishes an API to store and retrieve data. Using a request-based service you would probably use the HTTP methods to select an operation. (This is the reason for HTTP methods being a part of the handler's predicate.) Using an invocation-based service you would use method names for selecting the operation, especially naming rules, key-value coding. (This is the reason for selectors being a part of the dispatch process.) You can do both.
But you should not develop an invocation-based service using the HTTP method to select, whether some data has to be set or read. The Objective-C's pattern for this is the name of the accessor, not the method of the HTTP layer. This would be mixing up two worlds into one.
And you should not develop a request-based service and write your own dispatcher. We already did it.
There is a good rule of thumb: If your service relies heavily on HTTP, it is request-based, otherwise it is invocation-based. If you have a general handler for invocations (i. e. for authorization) this is possible and recommended for invocation-based services. But you shouldn't have access to the HTTP request inside many methods of your invocation-based service.
There are typical scenarios:
After you have created and cloned a cloud application as described here, you want to develop your service, test it, fix bugs and so on. You do not do this on our servers, but in a local test environment called Terrasphere.
To be more precise: Terrasphere is only a (lightweight) UI for terrasphered (the actual application server). It serves the tasks for the development a cloud application.
After launching terrasphere it will add a menu extra to your menu bar.
When a cloud application is launched it creates an HTTP server on a random port. This is very inconvenient if you want to use your cloud application (for example: you usually test your cloud application locally and thus you need to communicate with your cloud application). You would have to determine the port of your cloud application before you can actually use it. In contrast, Terrasphere is always running on port 10000. If you send a request to Terrasphere it will forward it to the correct cloud application. Terrasphere can do that because it knows about all cloud applications. This brings us to another thing Terrasphere is doing for you: Forwarding.
Terrasphere knows which cloud applications are currently running and it also knows their ports. If a request comes in, Terrasphere looks at the subdomain of the request's host and finds out which cloud application handles requests for this specific path component. If Terrasphere found a cloud application that can handle the request it forwards the HTTP request to that cloud application.
The whole point of Terrasphere is that you can test your cloud applications locally before pushing them to Objective-Cloud. Of course you want to test your cloud application in the same environment that it will be used when running it on Objective-Cloud. Basically, you have to mirror Objective-Cloud on your Mac. Since Objective-Cloud is a complex software we have extracted the most important components and packed them in an installer. When you install Terrasphere you also install a scaled down and simplified version of Objective-Cloud on your Mac. In addition Terrasphere tries to keep your local copy of Objective-Cloud up to date: When we deploy a new version of Objective-Cloud to our servers we also update Terrasphere. In turn Terrasphere will automatically ask you to download and execute the installer again if appropriate.
Terrasphere works great at long you are only working on one cloud application at a time. Each cloud application has a name. When a cloud application is deployed and a request comes in, you have to specify the name of the cloud application as part of the subdomain. For example https://helloworld.obcl.io
identifies the cloud application called helloworld
. As long you are working locally you make your request to localhost
and localhost
cannot have subdomains by default. This is why there can only ever be one cloud application locally. There are ways around this though: You can modify your /etc/hosts
file for example.
Once you launched Terrasphere you can launch your cloud application as usual in Xcode with Run. You can use the debugging tools.
You do not have to relaunch Terrasphere, when you relaunch your cloud application. Terrasphere detects the restart automatically.
Deploying your cloud applications to Objective-Cloud is done by using git. You simply push your source code to the git repository we created, when your cloud application has been created. This triggers to actions:
Building your cloud application is part of the deployment process.
We build your cloud application in a virtual machine with the following environment:
When building your cloud application we automatically set the build setting called OBJECTIVE_CLOUD_APPLICATION_NAME
.
You should not change the value of this build setting. It will break things. We may decide to not deploy your application of this build setting is not correct.
Your app is build by using xcodebuild like so:
xcodebuild -sdk macosx10.9 install \
-configuration Release \
-allTargets \
OBJECTIVE_CLOUD_APPLICATION_NAME=$yourApp \
CONFIGURATION_BUILD_DIR=~/Desktop \
FRAMEWORK_SEARCH_PATHS=$path_to_objective-cloud-frameworks \
OBJROOT=~/obj \
SYMROOT=~/sym \
DSTROOT=~/dst \
| tee xcodebuild.log
This means several things:
It may surprise you but the lifecycle of a cloud application is very similar to the lifecycle of an iOS application or an XPC service on a Mac: They are launched by demand . If there are no special circumstances apps usually run forever. However the operating system can decide to terminate running apps at almost any time. One reason that would cause apps to be terminated by the operating system is memory pressure: When the system determines that it may run out of memory soon it may decide to terminate apps at will. The same principles apply to cloud applications as well: Once your cloud application is deployed on Objective-Cloud it can be launched by incoming requests (usually made by users of your cloud application). Your cloud application is then running. Just like iOS, Objective-Cloud may terminate you cloud application at any time. We do that in certain situations:
If a cloud application has been terminated, it has to be relaunched. In most cases you would not recognize that. But there are some side effects:
If your cloud application behaves correctly (i. e. do not crash), the usual launch and termination process of OS X is used.
You have to keep in mind, that your application runs on different servers simultaneously. Every request reaching Objective-Cloud first goes through a load balancer and is distributed to on one of these application servers. Each is running Terrasphere. Terrasphere knows the available applications, launches your application if needed and then forwards the request to your application.
This leads to a behavior similar to the behavior terminating applications:
If you want to synchronize data between machines you should persist it into the database as usual in stateless services. The database is unique to the cloud application independently of the server it is running on.