\chapter{Dependence Management}
\label{chap:dep-management}
\index{dependence management|(textbf}

Before going into the details about how our architecture works, we present an
overview of the issues related to dependence management. We discuss how the
reification of dependence relationships can help support automatic
configuration, dynamic reconfiguration, fault-tolerance, and adaptation.

\section{Automatic Configuration}
\index{automatic configuration}

Users of modern computing environments have to deal with many different
devices, ranging from PDAs and embedded systems to powerful workstations and
servers. These devices are managed by different operating systems and depend
on different interfaces for configuration. As a result, users are overwhelmed
with the huge amount of manual configuration that these systems
require. In recent years, many of us have had to learn to deal with poorly
configured systems, looking for ``work-arounds'', just because it is too costly
to configure them properly.

In spite of the increasing need for self-configuring systems, not enough research
has been carried out in this field. We identify a few trends in this
area.

\begin{enumerate}
\item Systems such as MS-Windows provide graphical ``wizard'' interfaces that
help configuring applications and services as they are installed. However,
since dependence management is not addressed, it is very common to experience
errors in wizard operations, requiring manual intervention from users and
system administrators.

\item Operating systems such as Linux, rely on a tool called \emph{GNU
Autoconf}\index{autoconf} \cite{autoconf} to detect the characteristics of the
underlying hardware and software platforms and automate the configuration of
new applications and services at compile-time. Autoconf is used in a large
number of free software packages that are designed to run on a wide variety of
platforms. Obviously, the level of automatic configuration provided by such
tools is very limited since it is restricted to compile-time configuration.

\item The Debian Linux operating system \cite{debian} includes \class{dpkg}, a package
maintenance utility that manages the dependencies between the executables,
libraries, documentation, and data files associated with Debian software
packages. It maintains databases of dependencies that let users install,
update, and delete packages without compromising consistency. Even when
libraries are shared by multiple packages, \class{dpkg} is able to manage them
consistently. New packages can be read from a local CD or fetched from a
remote FTP site. 

To support the update of software packages that are being executed at the time
of the update, the utility renames the files related to the running version
and installs the update using the package official file names. Then, the next
time the package is restarted, the updated version is executed. This
mechanism allows, for example, system administrators to update the network
packages using FTP (a client of the network packages).

\item Jini\index{Jini} \cite{JINI:whitePaper98} provides simple mechanisms for
enabling plug-and-play Java services and facilitating configuration. Jini does
not address management of component-based applications and inter-component
dependence. It does not provide a model for specifying hardware and software
requirements.

\item Academic research in automatic configuration has addressed this problem
within the realm of software architecture and Architectural Description
Languages (ADLs). ADLs\index{ADL} such as Darwin\index{Darwin}
\cite{darwin:regis94,darwin:corba97} and UniCon\index{UniCon} \cite{Unicon96}
specify application architecture as a collection of modules linked by
\emph{bindings} and \emph{connectors}\index{connectors}, respectively. At
application startup time, the underlying system processes the application
architectural description, instantiates the required components, and
establishes the links among them.

ADL descriptions are limited to the internal architecture of a particular
application or service. They usually do not represent the interactions between
the application and the underlying system and the interactions among
applications. In addition, this approach requires pre-defined, fixed
architectural descriptions and does not work well in dynamic environments
where the architecture is not known until runtime.  We present a more detailed
description of related work in software architecture and ADLs in Section
\ref{sec:soft-arch}.
\end{enumerate}

Although we recognize the importance of the existing software tools and previous
research results in software architecture, we are convinced that
they are not enough to provide a definitive solution to the problem of
automating configuration.

What is missing is a model that lets each system and application component
specify its dependencies with respect to other components, applications,
system services, and hardware resources. With such an explicit representation
of dependencies, it becomes possible to implement services that support automatic
configuration.


\section{Dynamic Reconfiguration}
\label{sec:dyn-reconf}
\index{dynamic (re)configuration}

%We begin in section \ref{sec:motivation} by presenting some
%motivations for dynamic configuration in modern computer systems. Next, in
%section, \ref{sec:taxonomy} we present a brief taxonomy of dynamic
%configuration, discussing its different kinds. Finally, in section
%\ref{sec:scope}, we state the scope of this thesis with respect to dynamic
%configuration by defining what kinds of dynamic configuration we support and
%how our architecture could be extended to support the remaining kinds.

Besides helping to establish the \emph{initial} configuration automatically,
proper dependence management also helps support dynamic reconfiguration of
running applications and services. The importance of dynamic reconfiguration
can be understood by considering the rapid proliferation of the Internet and
the recent evolution of its supporting software.

The scope of Internet services continues to expand. It stretches to new
fields, reaches increasing numbers of people, and encompasses more and more
human activities in the virtual world of the World Wide Web.  Different forms
of electronic commerce ranging from airline ticket reservation to
pizza\index{pizza} delivery are now commonly available.  Activities such as
management of bank accounts, reading news, accessing financial information,
filing income taxes, submitting articles and registering for scientific
conferences, getting weather and natural disaster information, and
consolidating votes in presidential elections or referenda stress the
importance of service availability, reliability, and security.  However, the
rapid evolution of software requires frequent code updates and highly-dynamic
environments require reconfiguration of system parameters.  Maintaining the
flexibility and rapid growth of these systems while ensuring the service
requirements on such a scale\index{scalability} as the Internet is a difficult
problem.

Services must grow to meet increasing usage, new requirements, and new
applications.  However, flexibility usually conflicts with availability.  In
conventional systems, the service provider must often shut down, reconfigure,
and restart the service to update or reconfigure it.  In many cases, it
is unacceptable to disrupt the services for any period of time.  Disruption
may result in business loss, as in the case of electronic commerce, or it may
put lives in danger, as in the case of mission critical systems delivering
disaster information.  Research in dynamic reconfiguration
\cite{kramer90:configuration-programming,surgeon93,endler94:sbrc,darwin:corba97,olan98,bidan98,oreizy98,reconfiguration:workflow,iccds98,goudarzi99:consistent-dynreconf}
seeks solutions to this problem. 

By breaking a complex system into smaller components and by allowing the
dynamic replacement and reconfiguration of individual components with minimal
disruption of system execution, it is possible to combine high degrees of
flexibility and availability.

As pointed out by Goudarzi in \cite{goudarzi99:consistent-dynreconf}, dynamic
reconfiguration involves three basic issues: specification and management of
change, preservation of system consistency\index{consistency}, and
minimization of disruption to the provided service.

Previous approaches to dynamic reconfiguration are based on reconfiguration
scripts that must have some knowledge about the application architecture. However,
as mentioned before, if the architecture of the system being reconfigured is not known
until runtime, then an approach that requires \emph{a priori} knowledge of the
global system architecture is not appropriate.

Instead of dealing with global architectures, our approach focuses on
inter-component dependencies and lets users, system administrators, and
programs to replace components and reconfigure architectures at runtime.

The mechanisms for dependence management presented in Chapter
\ref{chap:architecture} provide the necessary support for software developers
to implement reconfigurable systems that preserve consistency and minimize
disruption\footnote{As we show in the next chapters, our architecture
\emph{per se} does not guarantee consistency and minimal disruption but it
provides the system support that is required to implement it.}.

%\subsection{A Taxonomy}
%\label{sec:taxonomy}

%classification criteria:

%1) at startup vs. on-the-fly

%2) w/ component participation vs. w/o component participation

%3) w/ application participation vs. w/o application participation

%4) single-item vs. multi-item

%5) single-node vs. multiple nodes

%6) consistency guarantees vs. no consistency guarantees

%7) manually vs. automatically

%7.1) manually:      interactively 
%     automatically: based on rules, based on dynamic properties
%                    based on programs, based on AI
%                    detect need for change -> apply change


\section{Fault-Tolerance}
\index{fault-tolerance}

Distributed systems may malfunction for a variety of reasons, including
network failures, node failures, software errors, and even programmed system
shutdowns for maintenance. In addition, in component-based systems it
is also common to have situations in which a part of the system fails while
the remaining parts continue to work properly. The challenge is to develop
fault-tolerant component-based systems that are able to detect partial
failures and change themselves to achieve a new configuration where system
execution can continue normally.  To carry out reconfiguration in the
event of failure, it is important to know which components depend on the
faulty component and which components depend on the parts of the system being
reconfigured.

It is hard to create robust and efficient systems if the dynamic dependencies
between components are not well understood. Furthermore, it is very common to
find cases, in which a component fails to accomplish its goal because an
unspecified dependency is not properly resolved. Sometimes, the graceful
failure of one component is not properly detected by other components leading
to total system failure. This thesis shows how proper dependence management
can help in the development of robust distributed systems.

\section{Adaptation}
\index{adaptation}

Highly heterogeneous platforms and varying resource availability motivates the
need for self-adapting software. Applications can improve their performance by
using different algorithms in different situations and switching from one
algorithm to another according to environmental conditions.  Significant
variations in resource availability should trigger architectural
reconfigurations, component replacements, and changes in the components' internal
parameters.

Consider, for example, the network connectivity of a mobile computer
\index{mobile computing} as its user commutes from work to home. As the user
switches from a wired connection at the office, to a wireless WAN using a
cellular phone, and finally, to a modem connection at home, the available
bandwidth changes by several orders of magnitude. The movement is also
accompanied by changes in latency, error rates, connectivity, protocols, and
cost.

Ideally, we would like to have a system capable of maintaining an explicit
representation of the dependencies among the network drivers, transport
protocols, communication services, and the application components that use
them. Only then, it would be possible to inform the interested parties when
significant changes occur. Upon receiving the change notifications,
applications and services can select different mechanisms, replace components,
and modify their internal configuration to adapt to the changes, optimizing performance.

%exception-handling not related to faults. For example, change in
%communication medium, or battery down, switching to a low-energy consumption mode.

\vspace{1cm}

In the next few chapters, we present a novel architecture for dependence
management and show how it facilitates the construction of flexible software systems
for dynamic environments.

\index{dependence management|)}