Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
193 lines (175 sloc) 12.1 KB
\documentclass{llncs}
\usepackage{makeidx} % allows for indexgeneration
\usepackage[pdftex]{graphicx} % PNGs
\usepackage{amsmath, amssymb} % algebra
\usepackage[utf8x]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[procnames]{listings} % for sourcecode
\usepackage{graphviz} % graphs
\usepackage{array,multirow} % tables
\usepackage{afterpage} % figures
\usepackage{float} % figures
\lstset{%
basicstyle=\small\ttfamily,
language=Ruby,
frame=lines,
numbers=left,
numberstyle=\rmfamily\tiny,
numbersep=3pt,
breaklines=true,
breakatwhitespace=true
}
\restylefloat{figure}
\begin{document}
\pagestyle{headings} % switches on printing of running heads
\mainmatter % start of the contributions
\title{Bithug - Coding Social}
\subtitle{A Code Repository Management Platform and Social Network}
\titlerunning{Bithug} % abbreviated title (for running head)
\author{Tim Felgentreff~ Konstantin Haase~ Johannes Wollert}
\date{\today}
\authorrunning{Felgentreff, Haase, Wollert} % abbreviated author list (for running head)
\tocauthor{Tim Felgentreff (Hasso-Plattner-Institute)\\
Konstantin Haase (Hasso-Plattner-Institut)\\
Johannes Wollert (Hasso-Plattner-Institut)}
\institute{Social Web Applications Engineering, Internet Technologies and Systems, Hasso-Plattner-Institut, Universität Potsdam, D-14482 Potsdam, Germany,\\
\email{\{tim.felgentreff, konstantin.haase, johannes.wollert\}@student.hpi.uni-potsdam.de}}
\maketitle
\begin{abstract}
This paper describes some of the design decisions taken in creating
the \emph{Bithug Coding Social} web service. Bithug is a free, highly
configurable and social code hosting service created during the ``Social
Web Applications Engineering'' seminar at HPI in 2009/10. Its purpose is to
provide a free and more versatile alternative to the git hosting
site \emph{Github} for universities and companies internal code hosting needs.
\end{abstract}
\section{Introduction}
The increased interactivity of the Web 2.0 has in recent years brought about a
shift in web technologies. One aspect of this shift is the increasing generation
of content by the consumer, clearly recognizable in the popularity of social
networks.
In 2007, the classic generators of content on the web, the programmers, got
their own social network where they could show off their interests and skills:
the social coding site \emph{Github}\cite{github:www}. On Github, a user can
create code repositories and freely share code with everyone else on the network.
Other users or projects can be ``followed'' which means, that every action on
and by the followed user is reported in a feed (on page and via RSS). Commits
can be commented on, people can collaborate on projects and code is online and
browsable.
All repositories on Github are initially open, however, for a monthly fee you
can buy private space on Github where only people who have been explicitly
granted access can view code.
\subsubsection*{Why Social?}
In the past, the sufficiency of self-organizing social networks even on large
scale projects has been demonstrated by open-source like the Linux
Kernel\cite{kernel:www}, X.org\cite{xorg:www} or the GNU Project\cite{gnu:www}.
In their footsteps, emerging social websites time and time again have proven how
loosely tied bodies are capable of organizing large
events.\cite{facebook:help}\cite{twitter:organize}\cite{facebook:organize}
In this manner, we want Bithug not only to be a service to host code, but a
network for exchanging ideas and organizing projects in a smaller university
or corporate environment to form a ``community'' much like the open-source
community which has formed on Github.
\subsubsection*{The Lazy Web}
Another change in how the web is used has come about with services like
FriendFeed, Twitter and most recently Facebook Lite. They provide short
messaging services to post notes. \emph{Friends} or \emph{Followers} can
receive and read those messages \ldots or not.\\
This is the concept we the ``Lazy Web'', where content is not generated
necessarily to be read. In social networks, important information will find
its way around.
We want Bithug to integrate with services like Twitter to let users generate
content about their activity. We hope that this will integrate with the
information flow some users might have come to like.
\section{Project Management as a Service}
Bithug, as an alternative code hosting service, intends to focus on the people
behind the code. That means, common hosting features such as forking and creating
repositories are made possible, but the most rewarding features lie in notifying
the people involved in a project and giving them a platform to communicate on. As
people and projects are highly diverse, we intend to offer and integrate a
number of web services, authentication methods and repository settings. Because
we want to enable Bithug to be used in an academic context and smaller companies,
configuration needs to be easily personalized and highly versatile.
\section{Design and Technical Execution}
\subsection{The Stack}
Our project is split into three major subprojects, which rest on many ruby
libraries some of which we had to modify to integrate with the project.
\vspace{-1em}
\begin{table}[H]
\setlength{\abovecaptionskip}{6pt} % 0.5cm as an example
\setlength{\belowcaptionskip}{-10pt} % integrate more tightly into text, this is explanatory, not result presentation
\renewcommand{\arraystretch}{1.7}
\centering
\begin{tabular}{>{\hspace{5pt}}r<{\hspace{5pt}}|>{\hspace{5pt}}l<{\hspace{5pt}}}
Bithug & The actual project code\\
BigBand & Parts of Bithug you can use in any Sinatra Project\\
MonkeyLib & Parts you can use in any Ruby project\\
\hline
Forked Libraries & krb5-auth, ohm, simple-krb5\\
\hline
Free Libraries & chronic, compass, haml, rack, rspec, twitter-oauth, yard\\
\end{tabular}
\end{table}
\subsection{Persistence}
\input{persistence}
\subsection{Sinatra}
Sinatra is a ruby web framework\cite{sinatra:www}, lately becoming a popular alternative to Ruby On Rails and Merb.
In contrast to those is has a small code base, does not ship with and persistence layer and does not focus on code
generation. In many cases this will result in better performance than a Rails application, especially for single
purpose applications, since the code size of Rails alone causes such a long dispatch that Sinatra performs much better.
Having a small and clean code base can also be useful, as it is easy for a developer to understand what is going on under the hood.
Also, for some not offering a out of the box ORM solution is a feature, rather than a short-coming, as it is easier to
choose another solution if the system does not assume it is coping with its own ORM (ActiveRecord, in that case). However,
it should be mentioned that those disadvantages have been reduced or removed in the upcoming Rails milestone 3.0.
\subsection{Using dynamic inheritance as means of configuration}
In class-based object-oriented programming inheritance is often used as specialization.
For instance, in an application managing costumers, the class Costumer might have the same
superclass as the class Administrator, as they might share some common logic and attributes.
This behavior can be used for application configuration, where one configuration option can be seen
as a special class inheriting from a more general Application class. In our application we use this
approach for our two core classes: User and Repository.
For instance: You want to use Kerberos authentication. With the previous explanation it could be possible
to have a Kerberos::User class, inheriting from Bithug::User, overwriting the authentication method.
This is actually very close to what we do internally. As you might suspect this approach fails when offering
combinable options. What if you to offer Kerberos and LDAP authentication both as stand-alone solution or
on as a fallback for the other (which is a typical network setup, in our experience). In a language that offers
multiple inheritance, you could create the classes Kerberos::User and Ldap::User, that both inherit from Bithug::User
and than create the classes KerberosWithLdapFallback::User and LdapWithKerberosFallback::User both inheriting
from Kerberos::User and Ldap::User. Would this language not be able to define classes at runtime, it would even be
more complicated, as you would have to generate all possible combinations at compile time. Ruby however does offer
runtime creation of classes. But it does lack multiple inheritance.
A third approach would be to change a classes inheritance chain by altering its superclass at runtime (or at compile
time, for that matter, which would be less dynamic). Upfront: Even though this is possible in most Ruby implementations,
it is considered extremely dangerous\footnote{Apart from maybe even seriously breaking your object space, you would have
to clear a couple of caches used by the underlying Ruby implementation to speed up method dispatch.}, and is not used
by Bithug. It should still be explained, as it helps to understand our implementation for not familiar with the Ruby
method dispatch. Let us take the above example: To configure a system that would first try to authenticate against Kerberos
and if that fails try LDAP authentication, you could change the superclass of Kerberos::User to Ldap::User which still
is a subclass of Bithug::User. If you implement a method Bithug::User.authenticate(login, password), that should return
true if authentication succeeds and false otherwise. Now, if Bithug::User.authenticate always returns false and both
Kerberos::User.authenticate and Ldap::User.authenticate return true if the authentication against LDAP/Kerberos succeeds,
the result of their superclass's authenticate the setup would be complete. This approach is somewhat comparable to context-
or aspect-oriented programming, where you are able to wrap aspects around an object\cite{apel2006aspectual}.
Ruby supports a concept called Mixins\cite{apel2004using}. Mixins are one use case for Ruby modules\footnote{Others are namespacing
and classes without instances.}. A Ruby module is defined like a Ruby class. You can define both instance and singleton
methods\footnote{Methods defined on class side, also known as class methods.}. However, as you cannot instantiate a module,
its instance methods are not directly usable. You can include such a module in a class. It is a common misconception – even among
long time rubyists – that by doing so the unbound methods\footnote{Ruby term for not yet belonging to an object, thus not being
callable.} are copied to the class and by doing so overwriting existing methods. In reality when including a module in a class,
a new class is created, containing all the modules instance methods. That class is inserted in the inheritance chain in-between
the original class and its superclass (or previously included modules). This allows a similar usage as changing the superclass
without its complications.
However, if you followed the above explanation closely, you might already see two major issues with that approach. As mentioned,
only the instance methods become part of the new class. The singleton methods are already bound to the module and cannot be
rebound to the class. The solution is a common pattern one will often fine in ruby programs: Use another mixin for the class methods
and include that mixin in the singleton class\footnote{A class every object in ruby has. It keeps all the singleton methods of an
object as instance methods and has that object as sole instance – hence singleton class.}.
The other problem is, that a module is inserted after the class in the inheritance chain, not in front of it. In the Kerberos/LDAP
example, Bithug::User.authenticate would always return false, since the Kerberos and LDAP implementations never get called. Our
solution to that is to have an empty class (i.e. without method definitions) called Bithug::User sub classing Bithug::AbstractUser.
All our common logic is placed inside AbstractUser. Now, if we include a module in Bithug::User, it is inserted in front of AbstractUser
in the inheritance chain, thus getting called.
\bibliographystyle{splncs}
\bibliography{bithug}
\clearpage
\end{document}