A better future for the FriendFeed tools and services ecosystem
FriendFeed is the only social-networking application I get and like using, and one of the reasons why is that it’s very community-oriented. The groups and friends approach of segmentation of attention easily directs both topic-oriented discussions and friends-oriented discussions towards the right people.
One other nice thing about FriendFeed is that, although not as popular as Twitter or Facebook, it has a healthy ecosystem of developers extending and building upon the platform. Lots of great user scripts, bookmarklets, feed-processing services, sms services and web apps have been developed and recently even more so with the release of the new API.
However, what I don’t like about the ecosystem is the separation of developers which develop tools and their potential users. Developers mostly use the official FriendFeed API Google group and FriendFeed API group for discussing programming issues and the API, while non-programmers mostly join the FriendFeed Google group and the FriendFeed Feedback and FriendFeed for beginners FF groups. This definitely isn’t the best solution for the future of the ecosystem. There is no central hub for the exchange of ideas between users and developers - users have a hard time finding existing tools and suggesting new ones while developers are have a hard time finding out what users need.
Enter FF tools and services – a new FriendFeed group for both developers and users to discuss existing and future FF-related tools and services. The goals I hope the group will help catalyze are:
- establish a central place where both developers and users of FriendFeed tools can go to sync up and discuss ideas,
- compile a single list of all FriendFeed tools and services – if you know or use a FF-related web app, bookmarklet or user script – just add it to this list and other users can use it to find cool apps,
- compile a single list of suggestions for future FriendFeed tools and services – if you have an idea for a cool FF web app or service which doesn’t yet exist – just add it to this list and a developer with some free time might build it.
And that’s it – a place where the FriendFeed tools and services ecosystem can grow. @izuzak
How to supercharge your free AppEngine quota?
AppEngine is awesome! Google’s cloud computing platform is hosting countless web apps, from Google products to innovative personal projects, and is constantly being upgraded with cool new features. And best of all, AppEngine charges for resources (computing, storage and bandwidth) using a freemium pricing model:
“Each App Engine application can consume a certain level of computing resources for free, controlled by a set of quotas. Developers who want to grow their applications beyond these free quotas can do so by enabling billing for their application and set a daily resource budget, which will allow for the purchasing of additional resources if and when they are needed.”
For example, the default free quota has a daily limit of 6.5 hours of CPU time with a maximum rate of 15 CPU-minutes/minute, while the billing enabled quota has 6.5 hours of free CPU time plus a maximum of 1,729 hours of paid CPU time with a maximum rate of 72 CPU-minutes/minute.
Billing for paid resources is controlled with a daily budget which developers set for each of their applications. The daily budget controls the amount of extra resources which may be purchased each day if the app steps over the free quota. The application developer defines how the daily budget is split between each of the billable quotas – outgoing bandwidth, incoming bandwidth, CPU time, stored data and number of recipients emailed. For example, $1 (the minimum daily budget) gets you 5 more CPU hours ($0.10 per CPU hour) and 4 more GB of outgoing bandwidth ($0.12 per GB).
Other than billable quotas, there are also unbillable quotas which increase when you switch to the paid model but are not billed. So, by switching to the paid model, irregardless to how you distribute your budget, your app gets a free bump in the:
- number of requests it can process from 1,300,000 to 43,000,000 and from 7,400 to 30,000 req/min,
- number of outgoing HTTP requests from 657,000 to 46,000,000 and from 3,000 to 32,000 req/min,
- number of memcache calls from 8,600,000 to 96,000,000 and from 48,000 to 108,000 calls/min,
and many others. These are very usable improvements by themselves for apps that need to process a lot of requests (or bursts of requests) which don’t consume a lot of CPU time, or apps that need to make a lot of outgoing HTTP requests that don’t consume a lot of bandwidth.
So here’s the idea for supercharging your free AppEngine quotas:
- switch you app to the paid model by enabling billing,
- enter the minimum daily budget ($1),
- distribute the budget over resources you are 100% sure will not consume their free quota (e.g. if you have a stateless app which doesn’t use the database, put the whole $1 in the stored data quota).
Since you put your budget on resources which won’t consume the entire free quota and since AppEngine doesn’t charge you anything if the app doesn’t step over the free quota – you are essentially getting a better free quota.
EDIT (Sept 5 2009): Yesterday, a week after my original post, Google released AppEngine SDK 1.2.5 which includes a major feature a lot of developers have been waiting for – XMPP support. What’s interesting and relevant for this post is that XMPP has it’s own quotas for the number of API calls, data sent, recipients messaged and invitations sent, and – none of these quotas are marked as billable. Therefore, using the recipe for supercharging your free quota will also get you a significant boost in your XMPP quotas (657k -> 46000k API calls, 657k -> 46000k recipients messaged and 1k -> 100k invitations sent). Pretty cool!
EDIT (Nov 2 2009): I just noticed that it is possible to increase the limit on the number of apps each AppEngine user can create. Currently, each user may create up to 10 AppEngine apps and there was no way to create more when you reached the limit, even by paying (or was there?). However, Google engineers have been approving explicit user requests for increases in the number of apps created on the official AppEngine group. People who have requested an increase have had the limit set to 20 apps.
Are there any other hacks for squeezing more out of AppEngine? @izuzak
Named arguments in JavaScript
While working on another project (pmrpc, which I will write about soon), the implementation of a feature came down to calling JavaScript functions with named arguments. Unfortunately, the JavaScript language (or EcmaScript to be exact) doesn’t support named arguments, rather only positional arguments.
Usually, JavaScript developers get around this by defining functions to accept a single object argument which acts like a container for all other named parameters:
// params is a container for other named parameters
function callMe(params) {
var param1 = params['param1'];
var param2 = params['param2'];
var param3 = params['param3'];
// do something...
}
var result = callMe({ 'param3' : 1, 'param1' : 2, 'param2' : 3 });
This solution works nicely when you are in the position to modify every function to be called this way. However, this is not always the case (e.g. when using external libraries), and also isn’t as readable as having a proper parameter list, and introduces code overhead in every function that implements this principle. What I needed for my project is something that enables calling any JavaScript function with named arguments, without modifying the function itself.
What I came up with (code presented below) is based on the following:
- using the toString method of the Function prototype, it is possible to retrieve a string representation of any function definition
- from the string representation, it is possible to parse the number, order and names of function parameters
- from a dictionary of named arguments, it is possible to construct an array of arguments in the correct order using the parsed representation
- using the apply method of the Function prototype, it is possible to dynamically call a function, passing an array of arguments instead of an argument list.
// calls function fn with context self and parameters defined in dictionary namedParams
function callWithNamedArgs( fn, self, namedParams ) {
// get string representation of function
var fnDef = fn.toString();
// parse the string representation and retrieve order of parameters
var argNames = fnDef.substring(fnDef.indexOf("(")+1, fnDef.indexOf(")"));
argNames = (argNames === "") ? [] : argNames.split(", ");
var argIndexes = {};
for (var i=0; i<argNames.length; i++) {
argIndexes[argNames[i]] = i;
}
// construct an array of arguments from a dictionary
var callParameters = [];
for (paramName in namedParams) {
if (argIndexes[paramName]) {
callParameters[argIndexes[paramName]] = namedParams[paramName];
}
}
// invoke function with specified context and arguments array
return fn.apply(self, callParameters);
}
// example function
function callMe(param1, param2, param3) {
// do something ...
}
// example invocation with named parameters
var result = callWithNamedArgs(callMe, this, { 'param3' : 1, 'param1' : 2, 'param2' : 3 });
This could also have been implemented as a Function prototype method and be called directly on a function object, which would simplify usage since the target function parameter wouldn’t have to be passed. But, if the CallWithNamedArgs function indeed was implemented prototype function, could the context parameter be removed also? I.e. is it possible to retrieve the current execution context (this object) of the target function within the CallWithNamedArgs method? The problem is that the execution context within the CallWithNamedArgs method is the Function object on which the CallWithNamedArgs method was called. But what we need is the execution context of the target function, which is the Function object on which the CallWithNamedArgs method was called. That is, what we need is the current execution context of the parent object. Any ideas? @izuzak


3 comments