Ruby on Embedded Devices
What is kinko.me
4 PGP-based email encryption
4 for your desktop and your mobiles
4 with your current email address
Also
4 comes on a dedicated device
ssshhh...
as of this afternoon we are crowdfunding.
Feel invited to check https://getkinko.com
Hardware
4 A10 1GHz Cortex-A8 ARMv7 CPU, VFPv3, NEON, Mali 400 GPU, CedarX VPU
4 512MB DDR3 RAM memory
4 SD storage
Compared to modern machines
4 CPU: 10x
4 IO throughput: ~50x
(RAM is ok, though)
Is this good enough?
4 Compared to Intel 386: yes
4 Compared with servers: a different usage patterns
4 low traffic volume
4 few requests to HTTPS frontend
Herding cats
Existing projects
4 nginx/dovecot: HTTP + IMAP servers (C)
4 GnuPG: PGP encryption (C)
4 imapsync: IMAP synchronization (Python)
4 bonjour, monit (C)
4 OpenSSH: tunnelling (C/ruby)
4 roundcube webmail: Webmail (PHP)
+ not so secret sauce
4 imapsync patch (Python)
4 configuration frontend (Ruby)
4 smtp server + client (Go)
4 installer (Ruby+Shell)
4 gluing code: (Ruby, Shell, C, Flex)
Why Ruby?
4 greatest language in the world
4 good network libraries
4 platform independent, kind of
4 Sinatra rocks
Why not Ruby?
gems + bundler
gems, bundler and all that mess
4 gems are platform independent. Well, mostly.
4 bundler: hard to manage over accounts
Performance
4 once started performance is ok:
4 ~10 to 20 pages rendered per second
4 startup performance is really bad:
4 starting a sinatra/ActiveRecord app: ~15 seconds
Performance Ruby vs C
# ~30 msecsdate
# ~150 msecsruby -e 'puts Time.now'
Lessons learned4 Configuration UI in ruby/sinatra (for
now)
4 everything else: mostly not.
Tipps & Tricks
1. UN*X is your friend
UN*X is your friend
4 caching: file system cache
4 resources: cleans up after you
4 shared storage: file system
4 built-in authentication: users + groups
4 also: ulimit, chroot, etc.
... Don't rebuild it in ruby
A custom logger in ruby:logger = Logger.new("#{Rails.root}/log/custom.log", 'daily')
logger.formatter = proc do |severity, time, _, msg| "#{time.strftime("%B %d %H:%M:%S")} #{severity} #{msg}\n"end
config.logger = logger
... Don't rebuild it in ruby, pt. 2
A custom logger in external application:
reader, writer = IO.pipe fork do Process.setpgrp STDIN.reopen reader writer.close exec("timestamp") end STDOUT.reopen writer STDERR.reopen writer reader.close
... Don't rebuild it in ruby, pt. 3
or simply:
rackup 2>&1 | timestamp
... Don't rebuild it
ditto:
4 daemons
4 process management
4 etc.
(Hello devops!)
2. Alternative Languages
fast and "portable": bash
#!/bin/bashset -euset -o pipefail echo "Yay!"
Commands are (sometimes) not portable:
echo -n "Is there a newline?"
small & fast: C
POSIX at your fingertips.
4 fast
4 small
4 source: somewhat portable; '#ifdef linux' FTW!
Pattern matching: flex
Pattern matching done quickly; in portable source code.
/* Replaces ${{NAME}} from the environment */
\$\{\{[a-zA-Z0-9_]+\}\} { yytext[yyleng-2] = 0; const char* env = yytext+3; const char* value = getenv(env); printf("%s", value ? value : ""); }
networking: Go
Go, the environment
4 fast, portable source
4 good networking + email libraries (even SSH!)
4 crosscompiling: easy
Go, the language
4 terrible.
jit: Distribute scripted binaries
Use jit!
http://github.com/radiospiel/jit
4 Works with C, flex, Go
4 Compiles just in or ahead of time
4 Native speed
(Built in bash, BTW)
jit: C Example
Source:
#!/usr/bin/env jit.cc#include <stdio.h>
void main() { printf("Hello world!\n");}
Run:
chmod +755 hello./hello
Links
4 flex: http://flex.sourceforge.net/
4 jit: http://github.com/radiospiel/jit
We are crowdfunding.
https://getkinko.com