Code Monkey home page Code Monkey logo

chicagoboss's Introduction

Chicago Boss: Start small, dream big

Build Status

Attention! This is a master branch supporting Erlang 18. For older Erlang versions use legacy branch.

Chicago Boss is a server framework inspired by Rails and written in Erlang. It offers all the conveniences of modern web development, including Comet. What sets Chicago Boss apart from other non-Erlang frameworks is that it can handle large amounts of traffic without any drop in performance. What sets Chicago Boss apart from other Erlang frameworks is that it is easy to set up and use.

WARNING: Chicago Boss does not work with Erlang R16B03 due to an error in erl_syntax

60-second Quickstart

After downloading and extracting, type

make
make app PROJECT=mynewproject
cd ../mynewproject
./init-dev.sh

For Windows, type

windows-make.bat
windows-make.bat app PROJECT=mynewproject
cd ..\mynewproject
start-server.bat

Then visit http://localhost:8001/ in your browser. Congratulations, you have a web server. There will be a lot of PROGRESS REPORTs on your console but everything should be running smoothly.

The project name should be a legal Erlang atom, i.e. start with a lowercase letter and contain only letters, digits, and underscores (for easy compatibility is recommended name the project dir and app name the same).

Dependencies

Admin Interface

You probably want to install the CB admin interface. Download it from

<https://github.com/ChicagoBoss/cb_admin>

Upgrades

Uprading used to be a pain but now it is easy. See README_UPGRADE

Database Setup

By default CB uses an in-memory database that needs no configuration. To start working with an actual database, See README_DATABASE

Philosophy and Features

Why another web framework? Because Rails apps are slow and Node apps are messy. Chicago Boss takes advantage of functional programming and under-the-hood compiler magic to provide clean, understandable controller logic, Django-style templates, and an ORM based on Erlang's parameterized modules. The best part is that the network I/O is 100% asynchronous so you can seamlessly integrate Comet endpoints into your app, and you never have to worry about a slow database query dragging down unrelated requests.

CB ships with all the tools you need to build a feature-ful website, including sessions, URL routing, filtering requests and post-processing responses, frameworks for sending and receiving email, JSON generation, Comet via long-poll and message queues, and internationalization (i18n). Read on for details.

Databases. Chicago Boss currently supports MySQL, PostgreSQL, Tokyo Tyrant, Mnesia, MongoDB, and Riak. In CB 0.5.4 and later, you can mix and match databases by configuring Boss to use vertical shards. For SQL databases, the conventions are similar to Rails (plural nouns for the table names, object_id for foreign keys, etc.).

BossRecords. Boss's take on ActiveRecord is called a BossRecord, which is an Erlang parameterized module on steroids. You instantiate a BossRecord like a regular parameterized module:

Article = article:new('id', "This is a title", "This is a body")

But then CB generates functions and attaches them to BossRecords, so you can write code like

{ok, SavedArticle} = Article:save()

Before saving to the database, the save() function will call a function called validation_tests(), where you can perform custom validation logic.

CB also generates getter functions which can be invoked directly in templates, so in your template you can write things like

{{ article.title }}

Speaking of which...

Templates. Chicago Boss uses ErlyDTL, an Erlang implentation of Django template language. In fact, Chicago Boss originated with a rewrite of ErlyDTL, and the same person maintains both projects so you always get the latest ErlyDTL features. Templates can access and loop over values stored in proplists, dictionaries, and BossRecords, so you can move data from the database to your templates with a minimum of massaging.

In addition, templates are tightly integrated with Boss's i18n machinery. The admin interface automatically parses templates for translatable strings, and Boss can choose which language to serve based on the request's Accept-Languages header and the calculated translation coverage for a particular page. Multi-language websites are easy to develop with Chicago Boss.

Controllers. Erlang's pattern-matching is a perfect fit for writing controller logic. Your controllers are passed the URL method (GET, POST) and a list of URL tokens, and just need to return a tuple telling Boss what to do, for example:

  • {ok, Variables} - render the default template with Variables
  • {render_other, Variables} - render another template
  • {redirect, URL} - redirect the request
  • {json, Proplist} - encode the Proplist as JSON and send to the client
  • {output, Data} - send Data to the client

If you come from Rails, you'll instantly notice the benefit of Erlang's language design: you don't need an ugly case request.method statement inside every action, you never have atrocities like render and return, and you can always see every variable that is in scope. In CB apps, controller logic is always concise and usually a pleasure to read.

Sessions. You can configure sessions to be stored in memory (ETS) or in an Mnesia database. The boss_session and boss_flash modules provide functions for storing and retrieving session information.

Routes. By default, Chicago Boss uses the same routing conventions as Ruby on Rails (/controller/action/id). You can customize the routes and provide a base URL in the priv/application.routes file. Of course, most routing occurs with the pattern-matching controller logic, e.g.

posts('GET', ["category", Category]) ->

You can then generate URLs to match controller patterns in your templates like so:

{% url action="posts" category="some category" %}

Email. Chicago Boss ships with a miniature MVC for sending multipart emails. Emails can be templated with ErlyDTL, and it is easy to provide plain-text and HTML versions of the same email. In testing environments, email can be sent directly to the recipient, or in production can be relayed to an SMTP server.

A Chicago Boss server can also receive email over SMTP. Each email address maps to a function in your incoming mail controller, so it is easy to write well-organized email applications. Your email controller has access to the exact same resources as your web controllers, including database requests, BossRecord instantiation, and the message queue; web and email are fully integrated.

Comet. It's simple to write a Comet endpoint in Chicago Boss. Unlike any other language, Erlang gives you the benefits of asynchronous network communcation without using callbacks. Here is a trivial example of a long-poll controller:

longpoll('GET', [Channel]) ->
    {ok, Timestamp, Messages} = boss_mq:pull(Channel, last),
    {json, [{timestamp, Timestamp}, {messages, Messages}]}.

The call to pull blocks until a message is received. Because processes are cheap in Erlang, the overhead of keeping alive a blocking request is very small (just a few kilobytes of memory, compared to megabytes in Rails). You can thus keep alive thousands of Comet request with just a few megabytes of memory. Also notice that the controller logic remains nice and clean (no callbacks). We can perform an arbitrary sequence of asynchronous network requests without increasing the scope level.

Events. An interesting feature of Chicago Boss is the events API called BossNews. With it, you can watch a record or a set of records for changes, then execute a callback when a change is witnessed. Combined with long-polling, you can provide a real-time view of your database on your website. Events can also be used to provide a clean separation of business logic and notification logic.

Tests. Chicago Boss has a kick-ass testing framework. Once you try it you won't go back. That's all I'll say for now.

Future Work

Most of Chicago Boss's planned features have been implemented at this point. It hasn't really been tested in a distributed environment, but it's already running on a few public-facing websites, and many more internal websites (or so I am told). It would be nice to add more databases (such as CouchDB and Oracle) and support horizontal sharding. The last main feature before 1.0 will be the ability to distribute apps written in Chicago Boss as standalone OTP applications.

Further Reading

See the FAQ and API files located at

http://www.chicagoboss.org/

If you need help getting started, check the new pdf tutorial:

http://www.chicagoboss.org/tutorial.pdf

Be sure to also check the wiki

https://github.com/ChicagoBoss/ChicagoBoss/wiki

There's also the mailing list:

http://groups.google.com/group/chicagoboss

If you want to contribute to CB

CODING_STANDARDS.md

View the CHANGELOG.md

CHANGELOG.md

chicagoboss's People

Contributors

aherranz avatar amarandon avatar bipthelin avatar braveh4rt avatar brigadier avatar choptastic avatar cstar avatar danikp avatar davidw avatar drobakowski avatar evanmiller avatar fdevibe avatar graeme-defty avatar igorclark avatar jgordor avatar kenr707 avatar kotedo avatar lucas-entronic avatar matthusby avatar mihawk avatar rambocoder avatar rojkov avatar runejuhl avatar solatis avatar strobe avatar tempaccounterl avatar timclicks avatar vorn avatar zkessin avatar ztmr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chicagoboss's Issues

{server, cowboy}, but MochiWeb appears to be responding to requests

In my boss.config, I have {server, cowboy} declared, but it only appears to be handling requests to subdirectories of /static/.

Here is the relevant HTTP headers from different requests:

/Server: MochiWeb/1.0 (Any of you quaids got a smint?)
/static/anythingServer: Cowboy

Am running {vsn, "0.8.0"}

Route for 404 error not working in 0.6.3

When have defined route for error 404 and requests absent controller the 404 error returned.

=ERROR REPORT==== 27-Oct-2011::08:38:11 ===
GET /someroute [alpha] 404 15ms

Seems, that boss_route_controller:handle_call({route, Url}, _From, State) does not checks if tokens are valid controller and method names.

boss_db process bottleneck

I was just reading boss_db.erl and realized it makes calls to a single process called boss_db to perform database operations. Wouldn't that result in One Giant Bottleneck?

Unhelpful error message when running make

$ cd /tmp

$ git clone https://github.com/evanmiller/ChicagoBoss.git

Initialized empty Git repository in /tmp/ChicagoBoss/.git/
remote: Counting objects: 2321, done.
remote: Compressing objects: 100% (1069/1069), done.
remote: Total 2321 (delta 1674), reused 1626 (delta 1202)
Receiving objects: 100% (2321/2321), 990.49 KiB | 228 KiB/s, done.
Resolving deltas: 100% (1674/1674), done.

$ cd ChicagoBoss/

$ make

==> ChicagoBoss (compile)

make: *** [all] Error 1

-> How to troubleshoot this issue further?

Operating System is Ubuntu 10.10. and Erlang version is:

Erlang R13B03 (erts-5.7.4) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

RegExp in routes

RegExp in the .routes file, for more flexible control url.
Something like:
{" /profile/[[0-9]] ", [{controller, "index"}, {action, "profile"}]}
{" /profile/search ", [{controller, "search"}, {action, "search"}]}

Mnesia error

When I try to save a new record using admin interface I got the following error:

{{aborted,{no_exists,greeting,attributes}},
{gen_server,call,[boss_db,{count,greeting,[]},30000]}}

Ubuntu 10.04, Erlang R14B01 (erts-5.8.2), Mnesia, latest version of CB

Include a version number

Hi Evan,

I wonder if it would be feasible to have a version number in ChicagoBoss that could be either queried via Makefile
such as:
make version
-> This is ChicagoBoss X.Y.Z

I see that I can get to the information by using in erl ...

(wildbill@rackbookpro)5> boss:module_info().
[{exports,[{start,0},
{stop,0},
{module_info,0},
{module_info,1}]},
{imports,[]},
{attributes,[{vsn,[291108095575550242669938456382961141132]},
{author,['Evan Miller [email protected]']}]},
{compile,[{options,[{outdir,"ebin"},
debug_info,debug_info,
{i,"include"}]},
{version,"4.7.5"},
{time,{2012,1,4,1,57,0}},
{source,"/private/var/www/ChicagoBoss-0.6.10_latest/src/boss/boss.erl"}]}]

The last line "source" has some versioning information in it that I am looking for (ChicagoBoss-0.6.10) but it would be nice
to have something like

boss:version() -> string()

Where string would be something like: {"ChicagoBoss",{0,6,10}.

—Kai

some notes for improved windows support

atm this is a bunch of raw notes as I went along

environment

  • Windows 7 x64
  • installed MSVC SDK 7.1 x64 version - not needed until Boss has NIFs
  • OpenSSL1 and R15B2 installed, added to path. I put the two *eay32.dll directly into R15B/bin folder.
  • installed Mozilla build tools3
  • run mingw from c:\mozilla-build\start-msvc10.bat
  • add R15B/bin to bash path also

Make

  • make all hangs on riakc
  • the rest seem fine
  • make boss is sufficient for our neeeds

rebar

  • copying rebar to rebar.cmd and editing first line as @echo off & path=%path%;%~dp0; & escript.exe "%~dpn0.cmd" %* & goto :eof allows rebar to work directly in a windows shell, assuming erlang is in the path
  • this should allow making a windows version of init.sh that actually works
  • init.sh should skip +K true, maybe use +A 4 instead
  • use werl for dev, run erl as service for prod

After all of this, the rest runs fine - like a BOSS!

packaging

If I have time tomorrow or friday I'll turn this into some sort of sfx exe for ChicaogoBoss.

transcript of a working install using the above.

    Setting SDK environment relative to c:\Program Files\Microsoft SDKs\Windows\v7.1\.
    Targeting Windows 7 x86 Release

    c:\ChicagoBoss>path=%path%;c:\erlang\bin;

    c:\ChicagoBoss>copy openssl\bin\*eay* c:\erlang\bin;
    \openssl\bin\libeay32.dll
    \openssl\bin\ssleay32.dll
            2 file(s) copied.

    c:\ChicagoBoss>\mozilla-build\start-msvc10.bat
    "Mozilla tools directory: c:\mozilla-build\"
    Visual C++ 9 Express directory: c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\
    Visual C++ 10 Express directory: c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\
    Windows SDK directory: c:\Program Files\Microsoft SDKs\Windows\v7.1\
    Windows SDK version: 7.1
    Setting environment for using Microsoft Visual Studio 2010 x86 tools.
    ERROR: Cannot determine the location of the VS Common Tools folder.
    Mozilla build environment: MSVC version 10.

    maas@SENDAI ~
    $ pwd
    /c/Users/maas

    maas@SENDAI ~
    $ cd /c/ChicagoBoss/

    maas@SENDAI /c/ChicagoBoss
    $ alias dir='ls --color -FGHa'

    maas@SENDAI /c/ChicagoBoss
    $ tar xzf /z/Downloads/ChicagoBoss-0.7.0.tar.gz

    maas@SENDAI /c/ChicagoBoss
    $ dir
    ./  ../  ChicagoBoss-0.7.0/

    maas@SENDAI /c/ChicagoBoss
    $ cd ChicagoBoss-0.7.0/

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ dir
    ./   .gitignore  Makefile   README_DATABASE  deps/     ebin/     priv/   rebar.config  skel.template
    ../  LICENSE     README.md  README_UPGRADE   doc-src/  include/  rebar*  skel/         src/

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ export PATH=$PATH:/c/erlang/bin

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ where erl
    c:\erlang\bin\erl.exe

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ where escript
    c:\erlang\bin\escript.exe

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ make
    ==> aleppo (get-deps)
    ==> bson (get-deps)
    ==> epgsql (get-deps)
    ==> gen_server2 (get-deps)
    ==> erlmc (get-deps)
    ==> erlydtl (get-deps)
    ==> gen_smtp (get-deps)
    ==> medici (get-deps)
    ==> misultin (get-deps)
    ==> mochiweb (get-deps)
    ==> mongodb (get-deps)
    ==> mysql (get-deps)
    ==> protobuffs (get-deps)
    ==> riakc (get-deps)
    ==> riakpool (get-deps)
    ==> ChicagoBoss-0.7.0 (get-deps)
    ==> aleppo (compile)
    src/aleppo_parser.yrl: Warning: conflicts: 1 shift/reduce, 0 reduce/reduce
    Compiled src/aleppo_parser.yrl
    Compiled src/aleppo.erl
    Compiled src/aleppo_parser.erl
    ==> bson (compile)
    Compiled src/bson.erl
    Compiled src/bson_tests.erl
    Compiled src/bson_binary.erl
    ==> epgsql (compile)
    Compiled src/pgsql_types.erl
    Compiled src/pgsql_idatetime.erl
    Compiled src/pgsql_sock.erl
    Compiled src/pgsql_fdatetime.erl
    Compiled src/pgsql_binary.erl
    Compiled src/pgsql.erl
    Compiled src/pgsql_connection.erl
    ==> gen_server2 (compile)
    Compiled src/gen_server2.erl
    Compiled src/priority_queue.erl
    ==> erlmc (compile)
    Compiled src/erlmc_conn.erl
    Compiled src/erlmc.erl
    ==> erlydtl (compile)
    Compiled src/erlydtl_parser.yrl
    Compiled src/i18n/sources_parser.erl
    Compiled src/i18n/po_generator.erl
    Compiled src/i18n/po_scanner.erl
    Compiled src/i18n/i18n_manager.erl
    Compiled src/i18n/blocktrans_parser.erl
    Compiled src/i18n/blocktrans_scanner.erl
    Compiled src/filter_lib/erlydtl_dateformat.erl
    Compiled src/filter_lib/erlydtl_slice.erl
    Compiled src/erlydtl_runtime.erl
    Compiled src/erlydtl_i18n.erl
    Compiled src/erlydtl_scanner.erl
    Compiled src/erlydtl_deps.erl
    Compiled src/erlydtl_filters.erl
    Compiled src/erlydtl.erl
    Compiled src/erlydtl_compiler.erl
    Compiled src/erlydtl_parser.erl
    ==> gen_smtp (compile)
    Compiled src/gen_smtp_server_session.erl
    Compiled src/smtp_util.erl
    Compiled src/smtp_server_example.erl
    Compiled src/socket.erl
    Compiled src/gen_smtp_server.erl
    Compiled src/binstr.erl
    Compiled src/gen_smtp_client.erl
    Compiled src/mimemail.erl
    ==> medici (compile)
    Compiled src/medici_sup.erl
    Compiled src/medici_port_sup.erl
    Compiled src/principe_table.erl
    Compiled src/medici_port_srv.erl
    Compiled src/principe.erl
    Compiled src/medici_native_conn.erl
    Compiled src/medici_native_controller.erl
    Compiled src/medici_conn_sup.erl
    Compiled src/medici_app.erl
    Compiled src/medici.erl
    Compiled src/medici_controller.erl
    Compiled src/medici_conn.erl
    ==> misultin (compile)
    Compiled src/misultin_websocket.erl
    Compiled src/misultin_websocket_draft-hybi-17.erl
    Compiled src/misultin_ws.erl
    Compiled src/misultin_websocket_draft-hybi-10_17.erl
    Compiled src/misultin_websocket_draft-hybi-10.erl
    Compiled src/misultin_websocket_draft-hixie-76.erl
    Compiled src/misultin_websocket_draft-hixie-68.erl
    Compiled src/misultin_socket.erl
    Compiled src/misultin_sessions.erl
    Compiled src/misultin_server.erl
    Compiled src/misultin_utility.erl
    Compiled src/misultin_req.erl
    Compiled src/misultin_acceptors_sup.erl
    Compiled src/misultin_cookies.erl
    Compiled src/misultin_acceptor.erl
    Compiled src/misultin.erl
    Compiled src/misultin_http.erl
    ==> mochiweb (compile)
    Compiled src/reloader.erl
    Compiled src/mochiweb_socket.erl
    Compiled src/mochiweb_response.erl
    Compiled src/mochiweb_request_tests.erl
    Compiled src/mochiweb_socket_server.erl
    Compiled src/mochiweb_util.erl
    Compiled src/mochiweb_multipart.erl
    Compiled src/mochiweb_io.erl
    Compiled src/mochiweb_http.erl
    Compiled src/mochiweb_mime.erl
    Compiled src/mochiweb_request.erl
    Compiled src/mochiweb_echo.erl
    Compiled src/mochiweb_headers.erl
    Compiled src/mochiweb_cover.erl
    Compiled src/mochiweb_cookies.erl
    Compiled src/mochiweb_acceptor.erl
    Compiled src/mochiweb.erl
    Compiled src/mochiweb_html.erl
    Compiled src/mochitemp.erl
    Compiled src/mochiutf8.erl
    Compiled src/mochilogfile2.erl
    Compiled src/mochilists.erl
    Compiled src/mochinum.erl
    Compiled src/mochijson.erl
    Compiled src/mochihex.erl
    Compiled src/mochijson2.erl
    Compiled src/mochifmt_std.erl
    Compiled src/mochifmt_records.erl
    Compiled src/mochiglobal.erl
    Compiled src/mochifmt.erl
    Compiled src/mochiweb_charref.erl
    ==> mongodb (compile)
    Compiled src/resource_pool.erl
    Compiled src/mvar.erl
    Compiled src/mongo_query.erl
    Compiled src/mongo_replset.erl
    Compiled src/mongo_cursor.erl
    Compiled src/mongo_protocol.erl
    Compiled src/mongodb_app.erl
    Compiled src/mongo_connect.erl
    Compiled src/mongodb_tests.erl
    Compiled src/mongo.erl
    ==> mysql (compile)
    Compiled src/mysql_recv.erl
    Compiled src/mysql_auth.erl
    src/mysql.erl:510: Warning: variable 'Reason' is unused
    Compiled src/mysql.erl
    Compiled src/mysql_conn.erl
    ==> protobuffs (compile)
    Compiled src/protobuffs_scanner.xrl
    Compiled src/protobuffs_parser.yrl
    Compiled src/protobuffs_parser.erl
    Compiled src/protobuffs_compile.erl
    Compiled src/protobuffs.erl
    Compiled src/protobuffs_scanner.erl
    Compiled src/pokemon_pb.erl
    ==> riakc (compile)
    Compiling src/riakclient.proto

    =INFO REPORT==== 2-Feb-2012::00:02:04 ===
    Writing header file to "riakclient_pb.hrl"

    =INFO REPORT==== 2-Feb-2012::00:02:04 ===
    Writing beam file to "riakclient_pb.beam"
    make: *** [all] Error 1

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ make
    ==> aleppo (get-deps)
    ==> bson (get-deps)
    ==> epgsql (get-deps)
    ==> gen_server2 (get-deps)
    ==> erlmc (get-deps)
    ==> erlydtl (get-deps)
    ==> gen_smtp (get-deps)
    ==> medici (get-deps)
    ==> misultin (get-deps)
    ==> mochiweb (get-deps)
    ==> mongodb (get-deps)
    ==> mysql (get-deps)
    ==> protobuffs (get-deps)
    ==> riakc (get-deps)
    ==> riakpool (get-deps)
    ==> ChicagoBoss-0.7.0 (get-deps)
    ==> aleppo (compile)
    ==> bson (compile)
    ==> epgsql (compile)
    ==> gen_server2 (compile)
    ==> erlmc (compile)
    ==> erlydtl (compile)
    ==> gen_smtp (compile)
    ==> medici (compile)
    ==> misultin (compile)
    ==> mochiweb (compile)
    ==> mongodb (compile)
    ==> mysql (compile)
    ==> protobuffs (compile)
    ==> riakc (compile)
    Compiling src/riakclient.proto

    =INFO REPORT==== 2-Feb-2012::00:06:05 ===
    Writing header file to "riakclient_pb.hrl"

    =INFO REPORT==== 2-Feb-2012::00:06:05 ===
    Writing beam file to "riakclient_pb.beam"
    make: *** [all] Interrupt


    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ less Makefile

    PREFIX:=../
    DEST:=$(PREFIX)$(PROJECT)
    ERL=erl
    REBAR=./rebar
    DB_CONFIG_DIR=src/boss/db_adapters/test_config
    SESSION_CONFIG_DIR=src/boss/session_adapters/test_config

    .PHONY: deps get-deps

    all:
            @$(REBAR) get-deps
            @$(REBAR) compile
            $(ERL) -pa ebin -pa deps/*/ebin \
                    -eval 'erlydtl:compile("src/boss/boss_html_error_template.dtl", boss_html_error_template, [{out_dir, "ebin"}])' \
                    -eval 'erlydtl:compile("src/boss/boss_html_doc_template.dtl", boss_html_doc_template, [{out_dir, "ebin"}])' \
                    -noshell -s init stop

    boss:
            @$(REBAR) compile skip_deps=true
             $(ERL) -pa ebin -pa deps/*/ebin \
                    -eval 'erlydtl:compile("src/boss/boss_html_error_template.dtl", boss_html_error_template, [{out_dir, "ebin"}])' \
                    -eval 'erlydtl:compile("src/boss/boss_html_doc_template.dtl", boss_html_doc_template, [{out_dir, "ebin"}])' \
                    -noshell -s init stop

    clean:
            @$(REBAR) clean

    edoc:
            $(ERL) -pa ebin -run boss_doc run -noshell -s init stop
    #$(ERL) -pa ebin -noshell -eval "boss_doc:run()" -s init stop

    app:
            @$(REBAR) create template=skel dest=$(DEST) src=$(PWD) appid=$(PROJECT) skip_deps=true

    get-deps:
            @$(REBAR) get-deps

    deps:
            @$(REBAR) compile

    test:
            @$(REBAR) skip_deps=true eunit

    test_db_mock:
            $(ERL) -pa ebin -run boss_db_test start -config $(DB_CONFIG_DIR)/mock -noshell

    test_db_mysql:
            $(ERL) -pa ebin -run boss_db_test start -config $(DB_CONFIG_DIR)/mysql -noshell

    test_db_pgsql:
            $(ERL) -pa ebin -run boss_db_test start -config $(DB_CONFIG_DIR)/pgsql -noshell

    test_db_mongodb:
            echo "db.boss_db_test_models.remove();"|mongo boss_test
            $(ERL) -pa ebin -run boss_db_test start -config $(DB_CONFIG_DIR)/mongodb -noshell

    test_session_cache:
            $(ERL) -pa ebin -run boss_session_test start -config $(SESSION_CONFIG_DIR)/cache -noshell

    test_session_mnesia:
            $(ERL) -pa ebin -run boss_session_test start -config $(SESSION_CONFIG_DIR)/mnesia -noshell

    test_session_mock:
            $(ERL) -pa ebin -run boss_session_test start -config $(SESSION_CONFIG_DIR)/mock -noshell

    test_db_riak:
            $(ERL) -pa ebin -pa deps/*/ebin -run boss_db_test start -config $(DB_CONFIG_DIR)/riak -noshell

    rebarize:
            @mv $(APPDIR)/*.app.src $(APPDIR)/src
            @mkdir $(APPDIR)/priv/rebar
            @cp skel/priv/rebar/boss_plugin.erl $(APPDIR)/priv/rebar/boss_plugin.erl
            @cp skel/init.sh $(APPDIR)
            @chmod +x $(APPDIR)/init.sh
            @cp skel/init-dev.sh $(APPDIR)
            @chmod +x $(APPDIR)/init-dev.sh
            @cp skel/rebar $(APPDIR)
            @chmod +x $(APPDIR)/rebar
            @cp skel/rebar.config $(APPDIR)
            @mkdir $(APPDIR)/src/test/functional
            @find $(APPDIR)/src/test -maxdepth 1 -name "*.erl" -exec mv {} $(APPDIR)/src/test/functional \;
            @mkdir $(APPDIR)/src/test/eunit
            @echo $(APPDIR) rebar-boss-ified
            @echo WARNING: your boss.config have not been changed, you need to set:
            @echo - in boss app section:
            @echo ---- {path, \"$(PWD)\"}
            @echo ---- {vm_cookie, \"my_secret_cookie\"} % Optional, defaults to "abc123"
            @echo - for each app defined:
            @echo ---- {path, \"../path/to/app\"}
            @echo INFO: you can safely remove the Makefile and start* files from your app dir
            @echo INFO: after the boss.config change, you can run:
            @echo cd $(APPDIR)
            @echo ./rebar boss \# Shows all boss-rebar commands
            @echo ./init.sh    \# Shows the new boot system commands


    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ make boss
    ==> ChicagoBoss-0.7.0 (compile)
    src/smart_exceptions/smart_exceptions.erl:182: Warning: variable 'Lf' is unused
    Compiled src/smart_exceptions/smart_exceptions.erl
    Compiled src/boss/boss_db_pt.erl
    Compiled src/simple_bridge/simple_bridge_response.erl
    Compiled src/simple_bridge/simple_bridge_request.erl
    Compiled src/boss/boss_session_adapter.erl
    Compiled src/boss/boss_db_adapter.erl
    Compiled src/boss/boss_cache_adapter.erl
    src/smart_exceptions/mapform0.erl:66: Warning: variable 'F' is unused
    Compiled src/smart_exceptions/mapform0.erl
    Compiled src/simple_bridge/simple_bridge_response_wrapper.erl
    Compiled src/simple_bridge/simple_bridge_request_wrapper.erl
    Compiled src/simple_bridge/simple_bridge.erl
    Compiled src/simple_bridge/mochiweb_bridge_modules/mochiweb_response_bridge.erl
    Compiled src/simple_bridge/misultin_bridge_modules/misultin_response_bridge.erl
    Compiled src/simple_bridge/mochiweb_bridge_modules/mochiweb_request_bridge.erl
    Compiled src/simple_bridge/simple_bridge_multipart.erl
    Compiled src/boss/session_adapters/boss_session_adapter_mock.erl
    Compiled src/simple_bridge/misultin_bridge_modules/misultin_request_bridge.erl
    Compiled src/boss/session_adapters/boss_session_adapter_mnesia.erl
    Compiled src/boss/session_adapters/boss_session_adapter_cache.erl
    Compiled src/boss/mq_adapters/boss_mq_adapter_bmq.erl
    Compiled src/boss/db_adapters/test_models/boss_db_test_parent_model.erl
    Compiled src/boss/db_adapters/test_models/boss_db_test_model.erl
    Compiled src/boss/db_adapters/boss_db_adapter_tyrant.erl
    Compiled src/boss/db_adapters/boss_db_adapter_riak.erl
    Compiled src/boss/inflector.erl
    Compiled src/boss/db_adapters/boss_db_adapter_pgsql.erl
    Compiled src/boss/db_adapters/boss_db_adapter_mock.erl
    Compiled src/boss/db_adapters/boss_db_adapter_mysql.erl
    Compiled src/boss/db_adapters/boss_db_adapter_mongodb.erl
    Compiled src/boss/cache_adapters/boss_cache_adapter_memcached_bin.erl
    Compiled src/boss/db_adapters/boss_db_adapter_mnesia.erl
    Compiled src/boss/boss_web.erl
    Compiled src/boss/boss_web_test.erl
    Compiled src/boss/boss_translator_sup.erl
    Compiled src/boss/boss_translator_controller.erl
    Compiled src/boss/boss_translator.erl
    Compiled src/boss/boss_test.erl
    Compiled src/boss/boss_sup.erl
    Compiled src/boss/boss_smtp_server.erl
    Compiled src/boss/boss_session_test.erl
    Compiled src/boss/boss_session_test_app.erl
    Compiled src/boss/boss_session_sup.erl
    Compiled src/boss/boss_web_controller.erl
    Compiled src/boss/boss_session_mock_sup.erl
    Compiled src/boss/boss_session_controller.erl
    Compiled src/boss/boss_session.erl
    Compiled src/boss/boss_router_sup.erl
    Compiled src/boss/boss_session_mock_controller.erl
    Compiled src/boss/boss_router.erl
    Compiled src/boss/boss_record_lib.erl
    Compiled src/boss/boss_router_controller.erl
    Compiled src/boss/boss_record.erl
    Compiled src/boss/boss_pq.erl
    Compiled src/boss/boss_news_sup.erl
    Compiled src/boss/boss_news.erl
    Compiled src/boss/boss_record_compiler.erl
    Compiled src/boss/boss_mq_sup.erl
    Compiled src/boss/boss_mq_controller.erl
    Compiled src/boss/boss_mq.erl
    Compiled src/boss/boss_mail_sup.erl
    Compiled src/boss/boss_mail_driver_smtp.erl
    Compiled src/boss/boss_news_controller.erl
    Compiled src/boss/boss_mail_controller.erl
    Compiled src/boss/boss_mail_driver_mock.erl
    Compiled src/boss/boss_mail.erl
    Compiled src/boss/boss_load.erl
    Compiled src/boss/boss_lang.erl
    Compiled src/boss/boss_json.erl
    Compiled src/boss/boss_flash.erl
    Compiled src/boss/boss_erlydtl_tags.erl
    Compiled src/boss/boss_env.erl
    Compiled src/boss/boss_files.erl
    Compiled src/boss/boss_db_test.erl
    Compiled src/boss/boss_db_sup.erl
    Compiled src/boss/boss_db_test_app.erl
    Compiled src/boss/boss_doc.erl
    Compiled src/boss/boss_db_mock_sup.erl
    Compiled src/boss/boss_db_cache.erl
    Compiled src/boss/boss_db_mock_controller.erl
    Compiled src/boss/boss_db_controller.erl
    Compiled src/boss/boss_controller_lib.erl
    Compiled src/boss/boss_controller_compiler.erl
    Compiled src/boss/boss_db.erl
    Compiled src/boss/boss_cache_sup.erl
    Compiled src/boss/boss_cache_controller.erl
    Compiled src/boss/boss_cache.erl
    Compiled src/boss/boss_compiler.erl
    Compiled src/boss/boss_app.erl
    Compiled src/boss/boss.erl
    Compiled src/bmq/bmq_sup.erl
    Compiled src/boss/boss_assert.erl
    Compiled src/bmq/bmq_channel_sup.erl
    Compiled src/bmq/bmq_controller.erl
    Compiled src/bmq/bmq.erl
    Compiled src/bmq/bmq_channel_controller.erl
    erl -pa ebin -pa deps/*/ebin \
                    -eval 'erlydtl:compile("src/boss/boss_html_error_template.dtl", boss_html_error_template, [{out_dir, "ebin"}])' \
                    -eval 'erlydtl:compile("src/boss/boss_html_doc_template.dtl", boss_html_doc_template, [{out_dir, "ebin"}])' \
                    -noshell -s init stop

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ make test
    ==> ChicagoBoss-0.7.0 (eunit)
    src/smart_exceptions/smart_exceptions.erl:182: Warning: variable 'Lf' is unused
    Compiled src/smart_exceptions/smart_exceptions.erl
    Compiled src/boss/boss_db_pt.erl
    Compiled src/simple_bridge/simple_bridge_response.erl
    Compiled src/simple_bridge/simple_bridge_request.erl
    Compiled src/boss/boss_session_adapter.erl
    Compiled src/boss/boss_db_adapter.erl
    Compiled src/boss/boss_cache_adapter.erl
    src/smart_exceptions/mapform0.erl:66: Warning: variable 'F' is unused
    Compiled src/smart_exceptions/mapform0.erl
    Compiled src/simple_bridge/simple_bridge_response_wrapper.erl
    Compiled src/simple_bridge/simple_bridge.erl
    Compiled src/simple_bridge/simple_bridge_request_wrapper.erl
    Compiled src/simple_bridge/mochiweb_bridge_modules/mochiweb_response_bridge.erl
    Compiled src/simple_bridge/misultin_bridge_modules/misultin_response_bridge.erl
    Compiled src/simple_bridge/mochiweb_bridge_modules/mochiweb_request_bridge.erl
    Compiled src/simple_bridge/simple_bridge_multipart.erl
    Compiled src/simple_bridge/misultin_bridge_modules/misultin_request_bridge.erl
    Compiled src/boss/session_adapters/boss_session_adapter_mock.erl
    Compiled src/boss/session_adapters/boss_session_adapter_cache.erl
    Compiled src/boss/session_adapters/boss_session_adapter_mnesia.erl
    Compiled src/boss/mq_adapters/boss_mq_adapter_bmq.erl
    Compiled src/boss/db_adapters/test_models/boss_db_test_parent_model.erl
    Compiled src/boss/db_adapters/test_models/boss_db_test_model.erl
    Compiled src/boss/inflector.erl
    Compiled src/boss/db_adapters/boss_db_adapter_tyrant.erl
    Compiled src/boss/db_adapters/boss_db_adapter_riak.erl
    Compiled src/boss/db_adapters/boss_db_adapter_pgsql.erl
    Compiled src/boss/db_adapters/boss_db_adapter_mock.erl
    Compiled src/boss/db_adapters/boss_db_adapter_mysql.erl
    Compiled src/boss/db_adapters/boss_db_adapter_mongodb.erl
    Compiled src/boss/cache_adapters/boss_cache_adapter_memcached_bin.erl
    Compiled src/boss/db_adapters/boss_db_adapter_mnesia.erl
    Compiled src/boss/boss_web.erl
    Compiled src/boss/boss_web_test.erl
    Compiled src/boss/boss_translator_sup.erl
    Compiled src/boss/boss_translator_controller.erl
    Compiled src/boss/boss_translator.erl
    Compiled src/boss/boss_test.erl
    Compiled src/boss/boss_sup.erl
    Compiled src/boss/boss_smtp_server.erl
    Compiled src/boss/boss_session_test_app.erl
    Compiled src/boss/boss_session_test.erl
    Compiled src/boss/boss_web_controller.erl
    Compiled src/boss/boss_session_sup.erl
    Compiled src/boss/boss_session_mock_sup.erl
    Compiled src/boss/boss_session.erl
    Compiled src/boss/boss_session_controller.erl
    Compiled src/boss/boss_session_mock_controller.erl
    Compiled src/boss/boss_router_sup.erl
    Compiled src/boss/boss_router.erl
    Compiled src/boss/boss_record_lib.erl
    Compiled src/boss/boss_router_controller.erl
    Compiled src/boss/boss_pq.erl
    Compiled src/boss/boss_record.erl
    Compiled src/boss/boss_news_sup.erl
    Compiled src/boss/boss_record_compiler.erl
    Compiled src/boss/boss_mq_sup.erl
    Compiled src/boss/boss_news.erl
    Compiled src/boss/boss_mq_controller.erl
    Compiled src/boss/boss_mq.erl
    Compiled src/boss/boss_mail_sup.erl
    Compiled src/boss/boss_mail_driver_smtp.erl
    Compiled src/boss/boss_news_controller.erl
    Compiled src/boss/boss_mail_driver_mock.erl
    Compiled src/boss/boss_mail_controller.erl
    Compiled src/boss/boss_mail.erl
    Compiled src/boss/boss_json.erl
    Compiled src/boss/boss_flash.erl
    Compiled src/boss/boss_load.erl
    Compiled src/boss/boss_lang.erl
    Compiled src/boss/boss_env.erl
    Compiled src/boss/boss_files.erl
    Compiled src/boss/boss_erlydtl_tags.erl
    Compiled src/boss/boss_db_test.erl
    Compiled src/boss/boss_db_sup.erl
    Compiled src/boss/boss_db_mock_sup.erl
    Compiled src/boss/boss_doc.erl
    Compiled src/boss/boss_db_test_app.erl
    Compiled src/boss/boss_db_mock_controller.erl
    Compiled src/boss/boss_db_cache.erl
    Compiled src/boss/boss_db_controller.erl
    Compiled src/boss/boss_controller_lib.erl
    Compiled src/boss/boss_controller_compiler.erl
    Compiled src/boss/boss_db.erl
    Compiled src/boss/boss_cache_sup.erl
    Compiled src/boss/boss_cache_controller.erl
    Compiled src/boss/boss_cache.erl
    Compiled src/boss/boss_compiler.erl
    Compiled src/boss/boss_app.erl
    Compiled src/boss/boss.erl
    Compiled src/boss/boss_assert.erl
    Compiled src/bmq/bmq_sup.erl
    Compiled src/bmq/bmq_channel_sup.erl
    Compiled src/bmq/bmq_controller.erl
    Compiled src/bmq/bmq.erl
    Compiled src/bmq/bmq_channel_controller.erl
      All 15 tests passed.

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ make app PROJECT=cb_tutorial
    ==> ChicagoBoss-0.7.0 (create)
    Writing ../cb_tutorial/start-server.bat
    Writing ../cb_tutorial/src/cb_tutorial.app.src
    Writing ../cb_tutorial/boss.config
    Writing ../cb_tutorial/src/mail/cb_tutorial_outgoing_mail_controller.erl
    Writing ../cb_tutorial/src/mail/cb_tutorial_incoming_mail_controller.erl
    Writing ../cb_tutorial/priv/init/cb_tutorial_01_news.erl
    Writing ../cb_tutorial/priv/static/chicago-boss.png
    Writing ../cb_tutorial/priv/static/favicon.ico
    Writing ../cb_tutorial/priv/cb_tutorial.routes
    Writing ../cb_tutorial/priv/rebar/boss_plugin.erl
    Writing ../cb_tutorial/init.sh
    Writing ../cb_tutorial/init-dev.sh
    Writing ../cb_tutorial/rebar
    Writing ../cb_tutorial/rebar.config

    maas@SENDAI /c/ChicagoBoss/ChicagoBoss-0.7.0
    $ cd ../cb_tutorial/

    maas@SENDAI /c/ChicagoBoss/cb_tutorial
    $ dir
    ./  ../  boss.config  ebin/  include/  init-dev.sh*  init.sh*  log/  priv/  rebar*  rebar.config  src/  start-server.bat*

    maas@SENDAI /c/ChicagoBoss/cb_tutorial
    $ ./init-dev.sh

    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,sasl_safe_sup}
                 started: [{pid,<0.39.0>},
                           {name,alarm_handler},
                           {mfargs,{alarm_handler,start_link,[]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]

    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,sasl_safe_sup}
                 started: [{pid,<0.40.0>},
                           {name,overload},
                           {mfargs,{overload,start_link,[]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]

    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,sasl_sup}
                 started: [{pid,<0.38.0>},
                           {name,sasl_safe_sup},
                           {mfargs,
                               {supervisor,start_link,
                                   [{local,sasl_safe_sup},sasl,safe]}},
                           {restart_type,permanent},
                           {shutdown,infinity},
                           {child_type,supervisor}]
    Eshell V5.9  (abort with ^G)

    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,sasl_sup}
                 started: [{pid,<0.41.0>},
                           {name,release_handler},
                           {mfargs,{release_handler,start_link,[]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
             application: sasl
              started_at: cb_tutorial@sendai
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,kernel_safe_sup}
                 started: [{pid,<0.46.0>},
                           {name,timer_server},
                           {mfargs,{timer,start_link,[]}},
                           {restart_type,permanent},
                           {shutdown,1000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,crypto_sup}
                 started: [{pid,<0.51.0>},
                           {name,crypto_server},
                           {mfargs,{crypto_server,start_link,[]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
             application: crypto
              started_at: cb_tutorial@sendai
    (cb_tutorial@sendai)1>
    =INFO REPORT==== 2-Feb-2012::00:28:45 ===
    Starting Boss in development mode....
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {global,boss_db_mock_sup}
                 started: [{pid,<0.63.0>},
                           {name,db_mock_controller},
                           {mfargs,{boss_db_mock_controller,start_link,[[]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,boss_db_sup}
                 started: [{pid,<0.61.0>},
                           {name,db_controller},
                           {mfargs,
                               {boss_db_controller,start_link,
                                   [[{adapter,boss_db_adapter_mock},
                                     {cache_enable,false},
                                     {shards,[]},
                                     {db_host,"localhost"},
                                     {db_port,1978}]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {global,boss_session_mock_sup}
                 started: [{pid,<0.67.0>},
                           {name,session_mock_controller},
                           {mfargs,
                               {boss_session_mock_controller,start_link,
                                   [[{adapter,boss_session_adapter_mock},
                                     {session_exp_time,525600},
                                     {session_key,"_boss_session"}]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {global,boss_session_sup}
                 started: [{pid,<0.65.0>},
                           {name,session_controller},
                           {mfargs,
                               {boss_session_controller,start_link,
                                   [[{adapter,boss_session_adapter_mock},
                                     {session_exp_time,525600},
                                     {session_key,"_boss_session"}]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =INFO REPORT==== 2-Feb-2012::00:28:45 ===
    Starting master services on cb_tutorial@sendai
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {<0.70.0>,bmq_sup}
                 started: [{pid,<0.71.0>},
                           {name,mq_controller},
                           {mfargs,
                               {bmq_controller,start_link,
                                   [[{adapter,boss_mq_adapter_bmq}]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {global,boss_mq_sup}
                 started: [{pid,<0.69.0>},
                           {name,mq_controller},
                           {mfargs,
                               {boss_mq_controller,start_link,
                                   [[{adapter,boss_mq_adapter_bmq}]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {global,boss_news_sup}
                 started: [{pid,<0.73.0>},
                           {name,news_controller},
                           {mfargs,{boss_news_controller,start_link,[[]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,inet_gethost_native_sup}
                 started: [{pid,<0.77.0>},{mfa,{inet_gethost_native,init,[[]]}}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,kernel_safe_sup}
                 started: [{pid,<0.76.0>},
                           {name,inet_gethost_native_sup},
                           {mfargs,{inet_gethost_native,start_link,[]}},
                           {restart_type,temporary},
                           {shutdown,1000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,boss_mail_sup}
                 started: [{pid,<0.75.0>},
                           {name,mail_controller},
                           {mfargs,
                               {boss_mail_controller,start_link,
                                   [[{driver,boss_mail_driver_smtp}]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,misultin}
                 started: [{pid,<0.79.0>},
                           {name,server},
                           {mfargs,{misultin_server,start_link,[{4096}]}},
                           {restart_type,permanent},
                           {shutdown,60000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {local,misultin}
                 started: [{pid,<0.80.0>},
                           {name,sessions},
                           {mfargs,
                               {misultin_sessions,start_link,[{<0.78.0>,600}]}},
                           {restart_type,permanent},
                           {shutdown,60000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.82.0>},
                           {name,{acceptor,1}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.83.0>},
                           {name,{acceptor,2}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.84.0>},
                           {name,{acceptor,3}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:45 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.85.0>},
                           {name,{acceptor,4}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.86.0>},
                           {name,{acceptor,5}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.87.0>},
                           {name,{acceptor,6}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.88.0>},
                           {name,{acceptor,7}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.89.0>},
                           {name,{acceptor,8}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.90.0>},
                           {name,{acceptor,9}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {<0.81.0>,misultin_acceptors_sup}
                 started: [{pid,<0.91.0>},
                           {name,{acceptor,10}},
                           {mfargs,
                               {misultin_acceptor,start_link,
                                   [<0.78.0>,#Port<0.3344>,8001,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,brutal_kill},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {local,misultin}
                 started: [{pid,<0.81.0>},
                           {name,acceptors_sup},
                           {mfargs,
                               {misultin_acceptors_sup,start_link,
                                   [<0.78.0>,8001,
                                    [binary,
                                     {packet,raw},
                                     {ip,{0,0,0,0}},
                                     {reuseaddr,true},
                                     {active,false},
                                     {backlog,128},
                                     inet],
                                    10,30000,http,
                                    {custom_opts,4194304,2000,false,
                                        #Fun<boss_web_controller.1.28399071>,true,
                                        undefined,true,
                                        ['draft-hybi-17','draft-hybi-10',
                                         'draft-hixie-76'],
                                        undefined,false,false,true,false}]}},
                           {restart_type,permanent},
                           {shutdown,infinity},
                           {child_type,supervisor}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {local,boss_sup}
                 started: [{pid,<0.56.0>},
                           {name,boss_web_controller},
                           {mfargs,
                               {boss_web_controller,start_link,
                                   [[{ip,"0.0.0.0"},{port,8001}]]}},
                           {restart_type,permanent},
                           {shutdown,5000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
             application: boss
              started_at: cb_tutorial@sendai
    (cb_tutorial@sendai)1>
    =INFO REPORT==== 2-Feb-2012::00:28:46 ===
    Loading routes from "c:/ChicagoBoss/cb_tutorial/priv/cb_tutorial.routes" ....
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {<0.92.0>,boss_router_sup}
                 started: [{pid,<0.93.0>},
                           {name,router_controller},
                           {mfargs,
                               {boss_router_controller,start_link,
                                   [[{application,cb_tutorial},
                                     {controllers,[]}]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1>
    =PROGRESS REPORT==== 2-Feb-2012::00:28:46 ===
              supervisor: {<0.95.0>,boss_translator_sup}
                 started: [{pid,<0.96.0>},
                           {name,translator_controller},
                           {mfargs,
                               {boss_translator_controller,start_link,
                                   [[{application,cb_tutorial}]]}},
                           {restart_type,permanent},
                           {shutdown,2000},
                           {child_type,worker}]
    (cb_tutorial@sendai)1> q().
    ok
    (cb_tutorial@sendai)2>

readme for heroku deployment?

I've been trying to piece together a ChicagoBoss Heroku app, and having virtually no experience with Erlang, it's proving difficult. I've got the ChicagoBoss example app up and running (after I discovered kerl and abandoned Ubuntu's apt-get old version of Erlang, it was pretty easy!) I was hoping that someone more knowledgeable than me could jump-start this process.

Here's a couple of resources that I think should be nearly enough with someone familiar with these technologies to get started:

I realize that Heroku has just recently started supporting Erlang and the process may change, but it should be a relatively simple affair and help get both ChicagoBoss and Erlang out into the world where more eyes can see them.

project skel

This file is details version of the boss.config file in the $CHICAGO_HOME/skel/ directory. Suggestion that add it to skel

%% https://github.com/evanmiller/ChicagoBoss/wiki/Configuration 

%% SYSTEM CONFIGURATIONS

[{boss, [
    {path, "{{src}}"},
    {applications, [{{appid}}]},
    {assume_locale, "en"},

%% Cookie value to use in production. Must be the same for all nodes in the cluster. 
    {vm_cookie, "en"},

%% Node name to use in production. Must be unique for all nodes in the cluster. Defaults to <application_name>@<host_name>
    {vm_name, "en"},

%% The largest number of processes that the VM is allowed to spawn. Defaults to 134217727 (the highest possible value).
    {vm_max_processes, 134217727},

%%%%%%%%%%%
%% Cache %%
%%%%%%%%%%%

%% The cache adapter to use. Currently the only valid value is memcached_bin. 
    {cache_adapter,"memcached_bin"},

%% Whether to enable the cache. Defaults to false.
    {cache_enable,false},

%% A list of cache servers ({Host, Port, PoolSize}). Defaults to [{"localhost", 11211, 1}].
    {cache_servers,[{"localhost", 11211, 1}]},

%% The maximum time to keep a cache entry, in seconds. Defaults to 60.
    {cache_exp_time,60}, 

%%%%%%%%%%%%%%
%% Database %%
%%%%%%%%%%%%%%


%% The hostname of the database. Defaults to "localhost".
    {db_host, "localhost"},
%% The port of the database. Defaults to 1978.
    {db_port, 3306},
%% The username used for connecting to the database (if needed).
    {db_username, "root"},
%% The password used for connecting to the database (if needed).
    {db_password, "root"},
%% The name of the database to connect to (if needed).
    {db_database, "boss_test"},
%% The database adapter to use. Valid values are: 
%%     mock - In-memory (non-persistent) database, useful for testing
%%     mnesia - Mnesia
%%     mongodb- MongoDB
%%     mysql - MySQL
%%     pgsql - PostgreSQL
%%     riak - Riak
%%     tyrant - Tokyo Tyrant
    {db_adapter, mysql},

%%  {db_write_mode, },
%%  {db_read_mode, },

%% A list of proplists with per-shard database configuration. 
%% The proplists override the above options, and should contain two additional options: 
%%  {db_shards, [ 
%%      [ 
%%          {db_host, "localhost"}, 
%%          {db_adapter, mysql}, 
%%          {db_port, 3306}, 
%%          {db_username, "root"}, 
%%          {db_password, "root"}, 
%%          {db_database, "boss_test"},
%%          {db_shard_id, shard_id_atom}, 
%%          {db_shard_models, [model_atom_1, model_atom_2, model_atom_3, etc]} 
%%      ] 
%%  ]},

%%%%%%%%%%%%%
%% Logging %%
%%%%%%%%%%%%%

    {log_dir, "log"},

%%%%%%%%%%
%% Mail %%
%%%%%%%%%%

%% The email delivery driver to use. Valid values are: 
    {mail_driver, "boss_mail_driver_smtp"},

%% The relay server for SMTP mail deliveries.
    {mail_relay_host, "smtp.163.com"},

%% The username used for connecting to the SMTP relay (if needed).
    {mail_relay_username, "[email protected]"},

%% The password used for connecting to the SMTP relay (if needed).
    {mail_relay_password, "mailserverpass"},


%%%%%%%%%%%%%%%%%%
%% MessageQueue %%
%%%%%%%%%%%%%%%%%%


%% For distributed configurations, the name of the master node. 
%% The master node runs global services (incoming mail, message queue, events, sessions). 
%% Should be an atom, e.g. somenode@somehost. 
%% The node name is specified in the -sname or -name argument in the startup script.
    {master_node, [email protected]},

%% Maximum age of messages in the [message queue], in seconds. Defaults to 60.
    {mq_max_age, 60},

%%%%%%%%%%%%%%%
%% Webserver %%
%%%%%%%%%%%%%%%

%% The port to run the server on. Defaults to 8001.
    {port, 8001},
%% The HTTP server to use. Valid values are: 
%%     mochiweb - The Mochiweb Web Server
%%     misultin - The Misultin Web Server (deprecated)
%%     cowboy - The Cowboy Web Server (COMET, WebSockets (soon), highly scalable, ...)
    {server, mochiweb},



%%%%%%%%%%%%%%
%% Sessions %%
%%%%%%%%%%%%%%

%% Selects the session driver to use. Valid values:
%%     cache - Store sessions in the configured cache servers. Requires cache_enable to be set to true.
%%     ets (default)
%%     mnesia
    {session_adapter, mock},

%% Whether to enable sessions. Defaults to true.
    {session_enable, true},

%% Cookie key for sessions. Defaults to "_boss_session"
    {session_key, "_boss_session"},

%% Expiration time for the session cookie. Defaults to 525600 
    {session_exp_time, 525600},

%% (optional, Mnesia sessions only) - List of Mnesia nodes, defaults to node()
    {session_mnesia_nodes, [node()]},

%% (optional, sets the Domain=x cookie option), 
%% this can be used by ex: to enable subdomain apps 
%% (*.domain.com) with the param ".domain.com" => {session_domain, ".domain.com"}
    {session_domain, ".domain.com"},

%%%%%%%%%%%%%%%
%% Templates %%
%%%%%%%%%%%%%%%

%% List of external modules to search for custom ErlyDTL tags.
    {template_tag_modules, []},

%% List of external modules to search for custom ErlyDTL filters.
    {template_filter_modules, []},

%%%%%%%%%%%%%%%%%%%%%
%% Incoming Emails %%
%%%%%%%%%%%%%%%%%%%%%

%% smtp_server_enable - Enable the SMTP server for incoming mail
    {smtp_server_enable, ""},

%% smtp_server_address - The address that the SMTP server should bind to. Defaults to {0, 0, 0, 0} (all interfaces).
    {smtp_server_address, {0, 0, 0, 0}},

%% smtp_server_domain - The domain name of the SMTP server
    {smtp_server_domain, "smtp.163.com"},

%% smtp_server_port - The port that the SMTP server should listen on. Defaults to 25.
    {smtp_server_port, 25},

%% smtp_server_protocol - The protocol that the SMTP server should use. Valid values are:
%%     tcp (default)
%%     ssl
    {smtp_server_protocol, "tcp"},

%%%%%%%%%
%% SSL %%
%%%%%%%%%

%% Enable HTTP over SSL
    {ssl_enable, true},
%% SSL options; see ssl(3erl)
    {ssl_options, []} 

]},

%% APPLICATION CONFIGURATIONS
{ mynewproject, [
    {path, "../mynewproject"},
    {base_url, "/"},
    {domains, ["all"]}
]}
].

simple_bridge as rebar dependency?

Is there an architectural decision in including parts of simple_bridge in src instead of as a dependency in rebar.config?

I do notice that in the latest simple_bridge, https://github.com/choptastic/simple_bridge the API for make_request changed, it now requires a tuple instead of Req:

Request = simple_bridge:make_request(mochiweb_request_bridge, {Req, "./wwwroot"})

bad match boss_record_compiler

load_and_execute_dev({"doc", ModelName, _}, Req) doesn't assume the possibility of static files.

=INFO REPORT==== 19-Dec-2010::17:10:20 ===
GET /doc/greeting 200
MODEL: "stylesheet.css"

=ERROR REPORT==== 19-Dec-2010::17:10:20 ===
{{badmatch,{error,enoent}},
[{boss_record_compiler,edoc_module,2},
{boss_web_controller,load_and_execute_dev,2},
{boss_web_controller,trap_load_and_execute,2},
{boss_web_controller,process_request,1},
{boss_web_controller,handle_request,3},
{mochiweb_http,headers,5},
{proc_lib,init_p_do_apply,3}]}

rebar_plugin windows paths issue

Hi, there's an issue with the pathname comparison here

https://github.com/evanmiller/ChicagoBoss/blob/master/skel/priv/rebar/boss_plugin.erl#L130

is_base_dir() ->
    rebar_utils:get_cwd() == rebar_config:get_global(base_dir, undefined).

I get drive letters one in upper- and one in lowercase and the comparison fails. So the whole build-process fails.
I resolved the issue for myself by wrapping the two strings in filename:nativename() but I'm not sure if this is a proper solution.

boss_web_controller.erl could use some better error messages

I was trying to find out why my code would not work at times and I decided to add some better error messages to the boss_web_controller. At lines 538 and 540 as of ChicagoBoss-0.6.3/ChicagoBoss-0.6.4 I added the reason of the failure
to the message.

A simple fix, and very helpful. Could you please be a bit more verbose in the error messages of the controller for easier debugging?

Thank you!

—Kai

utf8 handling in controllers

This works as return parameter of a controller's action:
{ok,{test,unicode:characters_to_binary("ódź参数", utf8, utf8)}}

But this {ok,{test,<<"ódź参数">>}} causes:

=ERROR REPORT==== 3-Apr-2012::14:17:43 ===
{badarg,[{example_chat_home_controller,index,3},
{boss_web_controller,execute_action,5},
{boss_web_controller,process_request,5},
{timer,tc,3},
{boss_web_controller,handle_request,3},
{mochiweb_http,headers,5},
{proc_lib,init_p_do_apply,3}]}

Also, having this in the controller's action body:

Var = <<"Україна">>

causes the same problem. I tried mochiweb and misultin.

This is in reference to your comment in the mailing group, that enclosing utf8 string as a binary should work in Erlang source code. http://groups.google.com/group/chicagoboss/msg/9dd91b5a27434bc5

HEAD requests result in HTTP 500 Internal Server Error

Using a recent clone of ChicagoBoss, a GET request will return content...

$ curl -i localhost:8001/
HTTP/1.1 200 OK
Set-Cookie: _boss_session=e2c5ad91cf9603d599082b5760f80cd3b49b535b; Version=1; Expires=Fri, 03-Aug-2012 12:22:20 GMT; Max-Age=525600; Path=/
Server: MochiWeb/1.0 (Any of you quaids got a smint?)
Date: Sat, 28 Jul 2012 10:22:20 GMT
Content-Type: text/html
Content-Length: 2

:D

...although a HEAD request for the same resource will fail.

$ curl -I localhost:8001/
HTTP/1.1 500 Internal Server Error
Set-Cookie: _boss_session=54ff1b363f3e2f78a2ab59ff152a487785dc38be; Version=1; Expires=Fri, 03-Aug-2012 12:22:28 GMT; Max-Age=525600; Path=/
Server: MochiWeb/1.0 (Any of you quaids got a smint?)
Date: Sat, 28 Jul 2012 10:22:28 GMT
Content-Type: text/html
Content-Length: 1500

Also notice that the Content-Length has somehow grown from 2 in the original request to 1500.

Comments not handled by boss_web_test:find_link_with_text

find_link_with_text has two alternatives for stepping past unwanted tags:

 find_link_with_text(LinkName, [{_OtherTag, _Attrs, []}|Rest]) ->
     find_link_with_text(LinkName, Rest);

and

 find_link_with_text(LinkName, [{_OtherTag, _Attrs, Children}|Rest]) when is_list(Children) ->
     find_link_with_text(LinkName, Rest);

A third is needed to deal with comments (and possibly other tags that have no children?)

 find_link_with_text(LinkName, [{_OtherTag, _Attrs}|Rest]) ->
     find_link_with_text(LinkName, Rest);

Extensions are ignored in tag_html

When compiling tag_html, Chicago Boss discards the extension from files in the tag_html directory. When using an editor that creates backup files by appending a string to the filename (e.g. Emacs and "~"), this results in compile errors, as the files have the same name when stripped of this extension:

{{badmatch,{error,"compilation failed: src/view/lib/tag_html"}},
 [{boss_load,load_view_lib,3,[{file,"src/boss/boss_load.erl"},{line,239}]},
  {boss_load,load_view_if_old,4,[{file,"src/boss/boss_load.erl"},{line,269}]},
  {boss_load,load_view_if_dev,3,[{file,"src/boss/boss_load.erl"},{line,299}]},
  {boss_web_controller,render_view,6,
                       [{file,"src/boss/boss_web_controller.erl"},{line,835}]},
  {boss_web_controller,execute_action,5,
                       [{file,"src/boss/boss_web_controller.erl"},{line,734}]},
  {boss_web_controller,process_request,5,
                       [{file,"src/boss/boss_web_controller.erl"},{line,460}]},
  {timer,tc,3,[{file,"timer.erl"},{line,194}]},
  {boss_web_controller,handle_request,3,
                       [{file,"src/boss/boss_web_controller.erl"},
                        {line,388}]}]}

As with ErlyDTL templates, Chicago Boss should only compile those files that end in ".html".

Syntax error in boss.config leads to cryptic error message

If boss.config is changed incorrectly, like below, and ./init.sh start-dev is invoked, the user receives the following message:

[{boss, [
...
    {server, misultin},#cowboy},
...
]},
$ ./init.sh start-dev
./init.sh: 25: ./init.sh: ERROR:: not found

When rebar is invoked directly, the error message is much more informative.

./rebar boss
==> cb_app (boss)
ERROR: boss failed while processing /home/user/cb_app: {'EXIT',{{case_clause,{error,{8,erl_parse,["syntax error before: ","'}'"]}}},
         [{boss_plugin,boss_config,1,
                       [{file,"priv/rebar/boss_plugin.erl"},{line,145}]},
          {boss_plugin,init,3,[{file,"priv/rebar/boss_plugin.erl"},{line,61}]},
          {boss_plugin,boss,2,[{file,"priv/rebar/boss_plugin.erl"},{line,32}]},
          {rebar_core,run_modules,4,[]},
          {rebar_core,execute,4,[]},
          {rebar_core,process_dir0,6,[]},
          {rebar_core,process_commands,2,[]},
          {rebar,main,1,[]}]}}

I know that this is largely to do with me forgetting use use Erlang comment syntax. But it was a little bit confusing when I encountered it.

Long polling crashes using Mitsulin

I was following along on your tutorial and kept getting 500s when doing the long polling example with {server, mitsulin} set in the config. I changed it to mochiweb and everything worked just fine. As OTP error messages go, the one I was getting didn't help too much. Here it is anyway:

=ERROR REPORT==== 20-Apr-2012::08:49:00 ===
module: misultin_http
line: 708
error in custom loop: killed serving request: {req,#Port<0.8914>,http,
{127,0,0,1},
49289,undefined,keep_alive,
undefined,
{1,1},
'GET',
{abs_path,
"/greeting/pull/1334936926257932"},
[],
[{'Host',"localhost:8001"},
{'Connection',"keep-alive"},
{'Referer',
"http://localhost:8001/greeting/live"},
{'Cache-Control',"max-age=0"},
{"X-Requested-With",
"XMLHttpRequest"},
{'User-Agent',
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.112 Safari/535.1"},
{'Accept',"/"},
{'Accept-Encoding',
"gzip,deflate,sdch"},
{'Accept-Language',
"en-US,en;q=0.8"},
{'Accept-Charset',
"ISO-8859-1,utf-8;q=0.7,*;q=0.3"},
{'Cookie',
"_boss_session=d1b34df9e7f8b8cb2fc3144e8d800520c71d2ec0"}],
<<>>,false}

Riak support

Hi everybody,

I am trying to build an app with CB using Riak for persistence. Riak's version is 1.1 and Riak Search 0.14.0. I changed boss.config to

{ db_port, 8098}
{ db_adapter, riak }

The application will run without any warnings or problems either from init-dev.sh or from init.sh,
but when I will try to save a model in the database I'll get the following (i get the same output
both from a webform and the admin console):

=ERROR REPORT==== 18-Apr-2012::13:33:36 ===
** Generic server <0.66.0> terminating
** Last message in was {tcp_closed,#Port<0.3149>}
** When Server state == {state,"localhost",8098,false,false,undefined,
undefined,
{[],[]},
1,[],infinity,100}
** Reason for termination ==
** disconnected
** exception exit: {disconnected,{gen_server,call,
[<0.65.0>,
{save_record,{post,id,"Awesome post!","ftw"}},
30000]}}
in function gen_server:call/3
in call from boss_pool:call/3
in call from boss_db:save_record/1
(adsrv_dash@ws-dhcp_3_156)5>
=CRASH REPORT==== 18-Apr-2012::13:33:36 ===
crasher:
initial call: riakc_pb_socket:init/1
pid: <0.66.0>
registered_name: []
exception exit: disconnected
in function gen_server:terminate/6
ancestors: [<0.65.0>,<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]
messages: []
links: [<0.65.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 610
stack_size: 24
reductions: 586
neighbours:
neighbour: [{pid,<0.65.0>},
{registered_name,[]},
{initial_call,{boss_db_controller,init,['Argument__1']}},
{current_function,{gen,do_call,4}},
{ancestors,[<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]},
{messages,[{#Ref<0.0.0.35477>,{error,disconnected}}]},
{links,[<0.64.0>,<0.66.0>,<0.63.0>]},
{dictionary,[]},
{trap_exit,false},
{status,runnable},
{heap_size,610},
{stack_size,34},
{reductions,406}]

=SUPERVISOR REPORT==== 18-Apr-2012::13:33:36 ===
Supervisor: {<0.64.0>,poolboy_sup}
Context: child_terminated
Reason: disconnected
Offender: [{pid,<0.65.0>},
{name,boss_db_controller},
{mfargs,{boss_db_controller,start_link,undefined}},
{restart_type,temporary},
{shutdown,brutal_kill},
{child_type,worker}]

=ERROR REPORT==== 18-Apr-2012::13:35:56 ===
** Generic server <0.72.0> terminating
** Last message in was {tcp_closed,#Port<0.3151>}
** When Server state == {state,"localhost",8098,false,false,undefined,
undefined,
{[],[]},
1,[],infinity,100}
** Reason for termination ==
** disconnected

=CRASH REPORT==== 18-Apr-2012::13:35:56 ===
crasher:
initial call: riakc_pb_socket:init/1
pid: <0.72.0>
registered_name: []
exception exit: disconnected
in function gen_server:terminate/6
ancestors: [<0.71.0>,<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]
messages: []
links: [<0.71.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 610
stack_size: 24
reductions: 477
neighbours:
neighbour: [{pid,<0.71.0>},
{registered_name,[]},
{initial_call,{boss_db_controller,init,['Argument__1']}},
{current_function,{gen_server,loop,6}},
{ancestors,[<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]},
{messages,[]},
{links,[<0.64.0>,<0.72.0>,<0.63.0>]},
{dictionary,[]},
{trap_exit,false},
{status,waiting},
{heap_size,233},
{stack_size,9},
{reductions,109}]

=SUPERVISOR REPORT==== 18-Apr-2012::13:35:56 ===
Supervisor: {<0.64.0>,poolboy_sup}
Context: child_terminated
Reason: disconnected
Offender: [{pid,<0.71.0>},
{name,boss_db_controller},
{mfargs,{boss_db_controller,start_link,undefined}},
{restart_type,temporary},
{shutdown,brutal_kill},
{child_type,worker}]

=ERROR REPORT==== 18-Apr-2012::13:35:56 ===
** Generic server <0.70.0> terminating
** Last message in was {tcp_closed,#Port<0.3150>}
** When Server state == {state,"localhost",8098,false,false,undefined,
undefined,
{[],[]},
1,[],infinity,100}
** Reason for termination ==
** disconnected

=CRASH REPORT==== 18-Apr-2012::13:35:56 ===
crasher:
initial call: riakc_pb_socket:init/1
pid: <0.70.0>
registered_name: []
exception exit: disconnected
in function gen_server:terminate/6
ancestors: [<0.69.0>,<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]
messages: []
links: [<0.69.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 610
stack_size: 24
reductions: 489
neighbours:
neighbour: [{pid,<0.69.0>},
{registered_name,[]},
{initial_call,{boss_db_controller,init,['Argument__1']}},
{current_function,{gen_server,loop,6}},
{ancestors,[<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]},
{messages,[]},
{links,[<0.64.0>,<0.70.0>,<0.63.0>]},
{dictionary,[]},
{trap_exit,false},
{status,waiting},
{heap_size,233},
{stack_size,9},
{reductions,109}]

=ERROR REPORT==== 18-Apr-2012::13:35:56 ===
** Generic server <0.76.0> terminating
** Last message in was {tcp_closed,#Port<0.3153>}
** When Server state == {state,"localhost",8098,false,false,undefined,
undefined,
{[],[]},
1,[],infinity,100}
** Reason for termination ==
** disconnected

=CRASH REPORT==== 18-Apr-2012::13:35:56 ===
crasher:
initial call: riakc_pb_socket:init/1
pid: <0.76.0>
registered_name: []
exception exit: disconnected
in function gen_server:terminate/6
ancestors: [<0.75.0>,<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]
messages: []
links: [<0.75.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 610
stack_size: 24
reductions: 485
neighbours:
neighbour: [{pid,<0.75.0>},
{registered_name,[]},
{initial_call,{boss_db_controller,init,['Argument__1']}},
{current_function,{gen_server,loop,6}},
{ancestors,[<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]},
{messages,[]},
{links,[<0.64.0>,<0.76.0>,<0.63.0>]},
{dictionary,[]},
{trap_exit,false},
{status,waiting},
{heap_size,233},
{stack_size,9},
{reductions,109}]

=ERROR REPORT==== 18-Apr-2012::13:35:56 ===
** Generic server <0.74.0> terminating
** Last message in was {tcp_closed,#Port<0.3152>}
** When Server state == {state,"localhost",8098,false,false,undefined,
undefined,
{[],[]},
1,[],infinity,100}
** Reason for termination ==
** disconnected

=CRASH REPORT==== 18-Apr-2012::13:35:56 ===
crasher:
initial call: riakc_pb_socket:init/1
pid: <0.74.0>
registered_name: []
exception exit: disconnected
in function gen_server:terminate/6
ancestors: [<0.73.0>,<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]
messages: []
links: [<0.73.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 610
stack_size: 24
reductions: 493
neighbours:
neighbour: [{pid,<0.73.0>},
{registered_name,[]},
{initial_call,{boss_db_controller,init,['Argument__1']}},
{current_function,{gen_server,loop,6}},
{ancestors,[<0.64.0>,boss_db_pool,boss_db_sup,boss_web,
boss_sup,<0.57.0>]},
{messages,[]},
{links,[<0.64.0>,<0.74.0>,<0.63.0>]},
{dictionary,[]},
{trap_exit,false},
{status,waiting},
{heap_size,233},
{stack_size,9},
{reductions,109}]

=SUPERVISOR REPORT==== 18-Apr-2012::13:35:56 ===
Supervisor: {<0.64.0>,poolboy_sup}
Context: child_terminated
Reason: disconnected
Offender: [{pid,<0.69.0>},
{name,boss_db_controller},
{mfargs,{boss_db_controller,start_link,undefined}},
{restart_type,temporary},
{shutdown,brutal_kill},
{child_type,worker}]

=SUPERVISOR REPORT==== 18-Apr-2012::13:35:56 ===
Supervisor: {<0.64.0>,poolboy_sup}
Context: child_terminated
Reason: disconnected
Offender: [{pid,<0.75.0>},
{name,boss_db_controller},
{mfargs,{boss_db_controller,start_link,undefined}},
{restart_type,temporary},
{shutdown,brutal_kill},
{child_type,worker}]

=SUPERVISOR REPORT==== 18-Apr-2012::13:35:56 ===
Supervisor: {<0.64.0>,poolboy_sup}
Context: child_terminated
Reason: disconnected
Offender: [{pid,<0.73.0>},
{name,boss_db_controller},
{mfargs,{boss_db_controller,start_link,undefined}},
{restart_type,temporary},
{shutdown,brutal_kill},
{child_type,worker}]

Ajax file upload

Hi All,

I am able to upload file by form post
I used Req:post_files()

but I want to implement same functionality by Ajax,I done following code but don't know how to get the data at erlang side
as post data will be in multipart i.e.
-----------------------------18585937711532326144600872827
Content-Disposition: form-data; name="file-0"; filename="MergedTable.rtf" Content-Type: application/rtf {\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\fswiss\fcharset0 Arial;}} {*\generator Msftedit 5.41.15.1507;}\viewkind4\uc1\pard\b\f0\fs24 Table : \b0 notification \b (From Address data will add in this table)
-----------------------------18585937711532326144600872827--

My Code

               var data = new FormData();
                jQuery.each($('#fileinput')[0].files, function(i, file) {
                    data.append('file-'+i, file);
                });


                $.ajax({
                    url: '/file/fileupload',
                    data: data,
                    processData: false,
                    type: 'POST',
                    mimeType: 'multipart/form-data',
                    success: function ( data ) {
                        alert( data );
                    }
                });

please help me

Respond to Mochiweb Req

As Mochiweb module is included in ChicagoBoss i have small query on it
I am implementing presence system who ever login will get presence of other user i.e. Roster implementation
here my code

spaceUserStatus('GET',[])->
  Value =  space_common_lib:waitforrequerst(Req),
 {json, [{result,"kk"}]}.

above function I will call by Ajax which will wait until the message comes to PId

in Comman lib

waitforrequerst(Req)->
    chat_room:wait(Req:cookie("user_id"), 1, self()),
    timer:apply_after(?COMET_TIMEOUT, ?MODULE, timeout_wait, [self()]),
    proc_lib:hibernate(?MODULE, wait, [Req]).

timeout_wait(Pid) ->  error_logger:info_msg("i m timeout",[]), Pid ! timeout.


wait(Req) ->
    receive
        timeout -> error_logger:info_msg("timeout printing ~p~n",[Req]), HOW TO RETURN ;
        Items when is_list(Items) ->
            Msgs = lists:flatten(lists:map(fun(X) -> format_message(X) end, Items)),
            space_common_lib:convert_to_json([{hello,<<"ravi">>}]),HOW TO RETURN;
        _ ->space_common_lib:convert_to_json([{hello,<<"ravi">>}]); HOW TO RETURN 
    end.

HOW TO RETURN is my Question

Here my request is unlimitedly waiting because I not able to Return, i get error_logger:info_msg("timeout printing pn",[Req]) in console but don't now how to return?

please help

My question is simple how do I response to my Ajax Request

Request to rename the internally used "user" to something else

Hi Evan,

People run repeatedly into the issue that they try to use the model "user" and end up in trouble.
It would be nice if ChicagoBoss itself could use a different model name that wold not clash with model names created by ChicagoBoss' users "user" model.

Thank you!
—Kai

Included find the needed stack trace:

=ERROR REPORT==== 27-Dec-2011::21:59:38 ===
Can't load module that resides in sticky dir

=ERROR REPORT==== 27-Dec-2011::21:59:38 ===
** Generic server boss_web terminating
** Last message in was timeout
** When Server state == {state,[],{ok,<0.519.0>},undefined,true}
** Reason for termination ==
** {{badmatch,{error,["code reload failed: user"]}},
[{boss_load,load_all_modules,3},
{boss_web_controller,'-handle_info/2-fun-0-',1},
{lists,map,2},
{boss_web_controller,handle_info,2},
{gen_server,handle_msg,5},
{proc_lib,init_p_do_apply,3}]}

=CRASH REPORT==== 27-Dec-2011::21:59:38 ===
crasher:
initial call: boss_web_controller:init/1
pid: <0.501.0>
registered_name: boss_web
exception exit: {{badmatch,{error,["code reload failed: user"]}},
[{boss_load,load_all_modules,3},
{boss_web_controller,'-handle_info/2-fun-0-',1},
{lists,map,2},
{boss_web_controller,handle_info,2},
{gen_server,handle_msg,5},
{proc_lib,init_p_do_apply,3}]}
in function gen_server:terminate/6
ancestors: [boss_sup,<0.57.0>]
messages: []
links: [<0.511.0>,<0.536.0>,<0.543.0>,<0.539.0>,<0.517.0>,<0.519.0>,
<0.515.0>,<0.503.0>,<0.507.0>,<0.58.0>]
dictionary: [{random_seed,{23116,24313,25941}},
{'exc var counter',10},
{boss_environment,development}]
trap_exit: false
status: running
heap_size: 6765
stack_size: 24
reductions: 68883
neighbours:
neighbour: [{pid,<0.543.0>},
{registered_name,re_cache},
{initial_call,{erlang,apply,2}},
{current_function,{inflector,re_cache_loop,1}},
{ancestors,[]},
{messages,[]},
{links,[<0.501.0>]},
{dictionary,[]},
{trap_exit,false},
{status,waiting},
{heap_size,1597},
{stack_size,4},
{reductions,246}]

ChicagoBoss doesn't work under Erlang R15B

Hi Evan,

It seems that CB 0.6.9 doesn't work in Erlang 15B

Jackie Dong experienced this:

Hi,
I created a users.erl module under model directory.
-module(user_db, [Id, Email, User_name, Password]).

(wildbill@NDC-DEV-01)2> UserDb = user:new(id, "a", "b", 123).
{user_db,id,"a","b",123}
(wildbill@NDC-DEV-01)3> UserDb:save().
** exception exit: {{badarg,
[{re,split,
[id,"-",[{return,list}]],
[{file,"re.erl"},{line,100}]},
{boss_news_controller,
handle_call,3,
[{file,
"src/boss/boss_news_controller.erl"},
{line,136}]},
{gen_server,handle_msg,5,
[{file,"gen_server.erl"},
{line,578}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},
{line,227}]}]},
{gen_server,call,
[{global,boss_news},
{created,id,
[{id,id},
{email,"a"},
{user_name,"b"},
{password,123}]}]}}
in function gen_server:call/2 (gen_server.erl, line 180)
in call from boss_record_lib:run_after_hooks/3 (src/boss/
boss_record_lib.erl, line 11)
in call from boss_db:save_record/1 (src/boss/boss_db.erl, line
195)
(wildbill@NDC-DEV-01)4>

boss_db:find/3 in 0.8.0 incorrect working

if i using find/2

(mybook@localhost)6> boss_db:find(users,[{name,"test"}]).
[{users,"users-1","test",
"778af09ce0b1760bb0dd0e7abef95984"}]

but if i using find/3

(mybook@localhost)7> boss_db:find(users,[{name,"test"}],1).
** exception error: no function clause matching
proplists:get_value(limit,1,all) (proplists.erl, line 222)
in function boss_db:find/3 (src/boss_db.erl, line 88)

in 0.7.* both statements work correct

Issue parsing .po file with comments

We have a gettext file created by poEdit, which contains a lot of additional data and comments.

The general file looks like this:

msgid ""
msgstr ""
"Project-Id-Version: Project\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2012-02-10 17:50+0100\n"
"PO-Revision-Date: 2012-02-10 17:50+0100\n"
"Last-Translator: Thomas Schaaf <[email protected]>\n"
"Language-Team: komola UG <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Poedit-KeywordsList: _;gettext;gettext_noop;_t\n"
"X-Poedit-Basepath: .\n"
"X-Poedit-Language: German\n"
"X-Poedit-Country: GERMANY\n"
"X-Poedit-SourceCharset: utf-8\n"
"X-Poedit-SearchPath-0: .\n"

#: strings.php:2
msgid "PAGE_NOT_FOUND"
msgstr "Seite nicht gefunden!"

This is a common format for gettext files.

However, Chicago Boss only seems to be able to parse this file, when I deleted all the "X-Poedit" lines and the #: file:line lines.

Problem with compile under Jenkins

The problem we're facing is that ./rebar compile does not work when run as a job under Jenkins. It seems to stem from the fact that the app gets checked out to a dir that's called workspace and then the boss.config path doesn't work out.
{ ourapp, [
{path, "../ourapp"},
{base_url, "/"}
]}

The problem could probably be changed on the jenkins side of things but I'd rather not have to specify the path at all or as "." in boss.config. When running rebar compile, boss_rebar runs boss_load:load_all_modules_and_emit_app_file(AppName, Dest)
which will go beserk in the root_priv_dir(App) function because it's treated as production and code:priv_dir(App) will return {error, bad_name}.
If we force the compile step to run as in development it works out fine. Is there a reason why compile and eunit can't always be treated as development when run?

Can't 'make'

Tokyo tyrant is running with:

$ ttserver -log ttserver.log boss-test.tct

Its log says:

2010-08-25T19:45:47+07:00 SYSTEM --------- logging started [24025] --------
2010-08-25T19:45:47+07:00 SYSTEM server configuration: host=(any) port=1978
2010-08-25T19:45:47+07:00 SYSTEM maximum connection: 1024
2010-08-25T19:45:47+07:00 SYSTEM opening the database: boss-test.tct
2010-08-25T19:45:47+07:00 SYSTEM service started: 24025
2010-08-25T19:45:47+07:00 INFO timer thread 1 started
2010-08-25T19:45:47+07:00 INFO worker thread 1 started
2010-08-25T19:45:47+07:00 INFO worker thread 2 started
2010-08-25T19:45:47+07:00 INFO worker thread 3 started
2010-08-25T19:45:47+07:00 INFO worker thread 4 started
2010-08-25T19:45:47+07:00 INFO worker thread 5 started
2010-08-25T19:45:47+07:00 INFO worker thread 6 started
2010-08-25T19:45:47+07:00 INFO worker thread 7 started
2010-08-25T19:45:47+07:00 INFO worker thread 8 started
2010-08-25T19:45:47+07:00 SYSTEM listening started

When I try to build ChicagoBoss:
$ make
mkdir -p ebin
cp src/boss/boss.app ebin/boss.app
mkdir -p ebin
cp src/medici/medici.app ebin/medici.app
mkdir -p ebin
cp src/mochiweb/mochiweb.app ebin/mochiweb.app
mkdir -p ebin
cp src/boss/boss_translator.app ebin/boss_translator.app
mkdir -p log Lang
erl -make
{"init terminating in do_boot",{undef,[{make,all,[]},{init,start_it,1},{init,start_em,1}]}}

Crash dump was written to: erl_crash.dump
init terminating in do_boot ()
make: *** [all] Error 1

no make help

It would be great if there was a make help option that provided an overview of the usage options.

Error compiling on Windows 7 64-bit

Hello,

I have Erlang, MinGW and Git installed and on my PATH. When running windows-make.bat in my ChicagoBoss source directory cloned from Git, I get the following error:

C:\Users\brandon\source\ChicagoBoss>windows-make.bat
==> aleppo (get-deps)
==> bson (get-deps)
==> epgsql (get-deps)
==> gen_server2 (get-deps)
==> erlmc (get-deps)
==> medici (get-deps)
==> mongodb (get-deps)
==> mysql (get-deps)
==> poolboy (get-deps)
==> protobuffs (get-deps)
==> riakc (get-deps)
==> boss_db (get-deps)
==> erlydtl (get-deps)
==> gen_smtp (get-deps)
==> misultin (get-deps)
==> mochiweb (get-deps)
==> proper (get-deps)
==> proper_stdlib (get-deps)
==> mimetypes (get-deps)
==> simple_bridge (get-deps)
==> cowboy (get-deps)
==> mochicow (get-deps)
==> ChicagoBoss (get-deps)
==> aleppo (compile)
==> bson (compile)
==> epgsql (compile)
==> gen_server2 (compile)
==> erlmc (compile)
==> medici (compile)
==> mongodb (compile)
==> mysql (compile)
==> poolboy (compile)
==> protobuffs (compile)
==> riakc (compile)
==> boss_db (compile)
==> erlydtl (compile)
==> gen_smtp (compile)
==> misultin (compile)
==> mochiweb (compile)
==> proper (compile)
'make' is not recognized as an internal or external command,
operable program or batch file.
ERROR: Command [compile] failed!

Here's what I get from the MinGW shell: http://iambrandontaylor.com/static/images/mingw-make-errors.PNG

What am I doing wrong?

Thank you,
Brandon

Make it possible to start additional OTP-Applications

It should be possible to specify additional (external) OTP-Applications to be started in the boss.conf file. It is usefull to implement some complex backend functionality (e.g. gen_fsm ...)

A possible solution would be to add an {included_applications, [myapp]} tag to boss.conf which will be added to the boss application's environment.
When the boss-app is starting it evaluates this list and starts the apps in boss' supervisor.

I can try to implement it if you think it is a clean way and the feature is wanted.

Boss crashes when project directory isn't the same as the project name

I noticed this error when I created a new application called chatboss and then renamed the project directory to ChatBoss. Boss then crashed on startup. But if I renamed the directory back to chatboss it worked out fine.

The project directory shouldn't need to be named the same as the application.

mongodb badarg error when i added new item.

I'm creating a table (model/test.erl) and it has two column: Id, and Text.

Then, i'm opening admin panel, and trying to add a data, when i clicked to save, it's giving an error:

{{badarg,[{re,split,[id,"-",[{return,list}]]},
{boss_news_controller,handle_call,3},
{gen_server,handle_msg,5},
{proc_lib,init_p_do_apply,3}]},
{gen_server,call,[boss_news,{created,id,[{id,id},{test,"ses"}]}]}}

Nevertheless, it's saving item successfully. The problem is only in redirect page. Is it bug or where is my wrong?

ChicagoBoss on Windows

I have downloaded the boss from here as a zip file. I followed the instructions given in the readme but I got the following error:
Rebar requires version 5 or + of Git to process.

Kindly help

timestamp is not current timestamp for boss_mq:now

here i m using boss_mq for chat purpose but i can see
Timestamp = boss_mq:now("updates"),
the timestamp is not current time it's showing date (Sun Dec 24 44597 22:08:45 GMT+0530 (IST))
after updateting message i m getting 1345209261371610 (as example) which after converting to datetime (Mon Dec 25 44597 20:46:11 GMT+0530 (IST)) which also not current datetime

is boss_mq broken?

please help

Error on boss_db:find, pgsql driver

I get an error when doing a search with boss_db, on a pgsql database

the entry in the database that causes the error is (not the one searched
for, the search is anything like xxx, not even using quotes on the searched term):

RSX 'Reality Synthesizer

Thanks in advance

The controller:

search('GET', [Search]) ->
Missing = boss_db:find(missing, [{missing_data, contains, Search}],
all, 0, missing_num, num_descending),
{ok, [{missing, Missing}]}.

The error:

Error:

{function_clause,
[{erlydtl_runtime,init_counter_stats,
[{error,
{error,error,<<"42601">>,
<<"syntax error in tsvector: "RSX 'Reality Synthesizer"">>,
[]}},
undefined]},
{cboss_view_missing_search_html,render_internal,4},
{cboss_view_missing_search_html,render,2},
{boss_web_controller,render_view,6},
{boss_web_controller,execute_action,5},
{boss_web_controller,process_request,5},
{timer,tc,3},
{boss_web_controller,handle_request,3}]}

Helper modules can't be used in the Custom tags

I need to create a widget, which consists of code (functions), and HTML.
To separate code and presentation, I put HTML into: /tag_html/widget.html, code into: /tag_modules/zzz_custom_tags.erl
and call from widget.html: {% widget_a foo="bar" %} or {% widget foo="bar" %}
Error!

How to create a Helper module without HTML?

What sense in the Custom tags? ErlyDTL's "include" tag does the same function:
{% Include "name_snippet.html" with person = "Jane" greeting = "Hello"%}

Migrations and Schema generation

I know this feature will probably be way in the future, but is there any plans to provide an ActiveRecord like schema migration and generation system? I know one of the draws of RoR is that it automates many tasks that can be easily automated (such as adding new tables), and I think CB might want to consider going in the same direction.

admin, mysql null values

The admin cannot handle NULL values. Adding the last_name column to the greetings table leads to the following error:

Error:
{function_clause,[{boss_db,data_type,[last_name,undefined]},
                  {admin_controller,'-model/3-fun-0-',1},
                  {lists,map,2},
                  {lists,map,2},
                  {lists,map,2},
                  {admin_controller,model,4},
                  {boss_web_controller,execute_action,3},
                  {boss_web_controller,trap_load_and_execute,2}]}

Seems like boss_db::data_type() doesn't recognize atom values. One possible way to fix:

diff --git a/SRC/boss/boss_db.erl b/SRC/boss/boss_db.erl
index 0a91450..8c00c24 100644
--- a/SRC/boss/boss_db.erl
+++ b/SRC/boss/boss_db.erl
@@ -203,6 +203,8 @@ data_type(_, _Val) when is_tuple(_Val) ->
     "datetime";
 data_type(_, _Val) when is_boolean(_Val) ->
     "boolean";
+data_type(_, _Val) when is_atom(_Val) ->
+    "NULL";
 data_type('id', _) ->
     "id";
 data_type(Key, Val) when is_list(Val) ->

Although I'm not aware if that's the appropriate solution.

helloworld tutorial not working

Hi,

I followed the tutorial but {output, "Hello, world!"} doesn't work. The browser says no template for that. I got this:

The requested template ("src/view/greeting/hello.html") was not found.

Thanks!

Non-parameterized Module DB Modules

I actually really like some aspects of chicago boss's DB modules I just wish it would generate a non-parameterized module version.

I'm not suggesting ditching the parameterized module versions but perhaps making it an option to be able to generate non-parameterized versions?

Failing ./rebar boss c=test_functional in quick start guide

In src/boss/boss_web_test.erl, Line 15 should be:

AdapterMod = list_to_atom(Adapter),

instead of:

AdapterMod = list_to_atom(lists:concat(["boss_db_adapter_", Adapter])),

Because during an ./init-dev.sh start, the following options get passed to boss_db/src/boss_db.erl/start/1
[{adapter,mock},
{cache_enable,false},
{shards,[]},
{is_master_node,true},
{db_host,"localhost"},
{db_port,1978}]

While during functional testing, the following options get passed to boss_db/src/boss_db.erl/start/1

[{adapter,boss_db_adapter_mock}]

and you have the following line in start/1:

Adapter = list_to_atom(lists:concat(["boss_db_adapter_", AdapterName])),

that converts mock into boss_db_adapter_mock and the way the bug is now, it makes the adapter name: boss_db_adapter_boss_db_adapter_mock

R15B helped me find this very quickly. CB is awesome.

Url tag not accepting template variables

The documentation indicates this is valid, but for me the template:

<a href="{% url action="eventdetail" id="{{ item.id }}" %}">{{ item.name }} - {{ item.date }}</a>

Renders to the page as:

<a href="/main/eventdetail/{{ item.id }}">Test Event - 2012-08-23</a>

The template renderer seems to be treating "{{ item.id }}" as a string literal instead of a template variable. Is this a bug, or am I missing something about the correct usage? Note: using {{ item.id }} outside of the url tag works as expected.

Thanks!

Test quick start project with-hyphens-in-name does not start

 make app PROJECT=test-chicago-boss
 ...
 cd ../test-chicago-boss
davidw@catlow:~/downloads/test-chicago-boss $ ./init-dev.sh 
./init.sh: 55: ERROR:: not found

If I try and do things by hand:

./rebar boss c=start_dev_cmd
ERROR: Failed to extract name from /home/davidw/downloads/test-chicago-boss/src/test-chicago-boss.app.src: {1,
                                                                                                        erl_parse,
                                                                                                        "bad term"}

Which leads me to:

{application, test-chicago-boss, [
    {description, "My Awesome Web Framework"},
    {vsn, "0.0.1"},
    {modules, []},
    {registered, []},
    {applications, [kernel, stdlib, crypto, boss]},
    {env, []}
 ]}.

Indeed, test-chicago-boss is a bad atom. It should probably be quoted.

db tests don't work in Ubuntu 11.04

Hi Evan!

After I had applied the fix mentioned in #12 and run the tests for the mock adapter I got the following output

rozhkov@x301:~/work/chicago/ChicagoBoss (fix-src-discrepancy)$ make test_db_mock
erl -pa ebin -run boss_db_test start -config src/boss/db_adapters/test_config/mock -noshell
Root test                                                   
=INFO REPORT==== 1-May-2011::14:51:24 ===
    application: boss_db_test
    exited: {bad_return,
                {{boss_db_test_app,start,[normal,[]]},
                 {'EXIT',
                     {noproc,
                         {gen_server,call,
                             [boss_news,
                              {created,"boss_db_test_parent_model-1",
                                  [{id,"boss_db_test_parent_model-1"},
                                   {some_text,<<"foo">>}]}]}}}}}
    type: temporary

Looks like a boss_news process is missing. Could you please clarify the docs a bit on what the news.erl file is for?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.