Polyglot is a distributed web framework that allows programmers to create web applications in multiple programming languages
Polyglot is a distributed web framework that allows programmers to create web applications in multiple programming languages
Polyglot is experimental and incomplete at the moment. Please use with caution and at your own risk!
Polyglot allows programmers to collaborate and develop a single web app using multiple programming languages, libraries, environments and even different versions of the same language.
What does this mean?
It means no more programming language wars -- programmers can use the best language for the job and/or their favorite language to write different parts of the same web app.
It can also mean no dependency hell. Different parts of the same web app can use different libraries. So if you have a new feature that requires using a newer version of the same library you used before, you can just go ahead and use it.
This also means you can scale and evolve your web app, building on what you have built before, and taking down only those parts that you need to replace, and even replace your web app in a less destructive way. No more 'big bang' approach to upgrading your web platform!
So what's the catch?
Polyglot increases the complexity in the effort to develop web apps. Unlike frameworks like Rails or Django or Express, Polyglot doesn't exist to make life easier for the programmer. In fact it adds the complexity of the application, not only in the deployment but also in the development.
As a programmer you trade complexity and effort for something you think is more important for the web app you're creating. In Polyglot, we are trading complexity and effort for:
Polyglot is not for all web apps. You should only use Polyglot for web apps that need to be scaled in a highly performant way and/or need to be incrementally developed in multiple programming languages. For example, if your web app never needs to scale beyond a single server, you're probably better off using some other single language framework. And if once your web app is created, you or anyone else never need to add new features, Polyglot is probably not suitable either.
Why would you want to develop a web app in multiple programming languages? There are good, practical reasons:
Why is even a 'web framework'? Web frameworks make life easier for programmers by making it easier to create web apps. While the added complexity of writing web apps with Polyglot make things more difficult initially, over time, the application is easier to extend and to evolve. With a bigger picture in mind, Polyglot does make life easier for programmers.
Polyglot has a very simple and basic architecture. It consists of 3 main components:
Essentially, the Polyglot architecture revolves around using a broker to disassociate the processing units (responders) from the communications unit (acceptor), allowing the responders to be created in multiple languages.
###Flow
The acceptor is a communications unit that interacts with the external world (normally a browser but can also be another server calling an API). The default implementation is written in Go. The acceptor is sessionless and its main task is to accept requests and sends them to the broker, then receives the response and reply to the requestor. The communications with the broker is through ZMQ.
You can also extend an existing application by creating a controller in that application as an acceptor. There can be one or more acceptors in a single Polyglot application, for load-balancing purposes.
The broker is a load-balancing broker implemented in Go and communicates with both the acceptors and the responders through ZMQ. The broker queues responders that are registered with it and load balances amongst them using round-robin.
Responders are processing units that can be written in any programming language that can communicate with the broker through ZMQ. Responders are normally written as standalone processes. All responders essentially do the same thing, which is to process incoming requests and returns a message to the broker. Each responder must have a route ID, which is in the format of:
/_/For example GET/_/hello/world is a route ID.
Each responder must also have a unique ID that identifies itself across all routes. It's the developer's responsibility to ensure the uniqueness of the ID as the broker will not check its uniqueness.
My development environment in OS X Mavericks but it should work fine with most *nix-based environments.
First, install ZeroMQ 4.0.4.
Next, clone this repository in to a Go workspace. The default acceptor is written in Go and you'll need to build it.
The default Polyglot acceptor is written in Go. To install, just run:
go buildThis should create a program called polyglot. To run the default acceptor:
./polyglotTo configure the acceptor, modify the config.json file and restart the acceptor. The acceptor also creates a log file called acceptor.log that shows the acceptor's activities.
The Polyglot broker is written in Go. To install, go to the broker directory and run:
go buildThis should create a program called broker. To run the broker:
./brokerThe broker creates a log file called broker.log that shows the broker's activities. There is a command line admin tool called polyadm in the polyadm directory.
The set of example responders are in the responders directory. To run them, you can either start them individually or you can use Foreman like I do.
To start the responders individually, go to the respective directories for eg the ruby directory and do this:
ruby responder.rbThis will start up the hello Ruby responder. Note that you have only started 1 responder. To start up and manage a bunch of responders, open up Procfile in the responders directory.
hello_ruby: ruby -C ./ruby responder.rb
hello_go: ./goresp/gorespYou will notice that the file consists of lines of configuration that starts up the responders. Now open up the file .foreman.
concurrency:
hello_ruby=5,
hello_go=5As you can see, each line after concurrency: is a responder. The number configuration is the number of responders you want to start up. In this case, I'm starting up 2 hello_rubyand hello_go responders each.
To start all the responders at once:
foreman startIf you want to run this in the background without being cut off when you log out:
nohup foreman start &Foreman is used for development and testing purposes only. If you want to run this in production, use Foreman to export out the configuration files in Upstart or launchd etc. Foreman should not be used in production.
Writing responders are quite easy. There are basically only a few steps to follow:
/_/ and then the route path. For example, if you want to set up a responder for a GET request going to the route hello then set up the route ID to be GET/_/helloThe examples below shows how this can be done in various languages. The full list of responders are in the responders directory, including sample (Hello World type) responders for:
Please send pull requests for sample responders in other languages!
This example uses the high-level C library CZMQ. To build the responder, please build the CZMQ library first then run:
makeThis will create the file responder which you can run from command line as a binary.
…This example uses the ffi-rzmq gem and returns a "Hello World" back to the browser.
require 'securerandom'
require 'bundler'
Bundler.require
broker = "tcp://localhost:4321"
routeid = "GET/_/hello/ruby"
identity = SecureRandom.uuid
puts "#{routeid} - #{identity} responder ready"
ctx = ZMQ::Context.new
client = ctx.socket ZMQ::REQ
client.identity = identity
client.connect broker
client.send_string routeid
loop doNo open issues yet, or sync has not completed.