# rkh/papers

Switch branches/tags
Nothing to show
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}