Custom URL Patterns¶
Suppose your project requires a different URL convention than the normal /app/page/
. For example, you might need the user id in between the app and page: e.g. /app/userid/page/
.
DMP’s default patterns are added when you include DMP’s urls.py
in your project. DMP iterates your local apps, and it adds a custom resolver for each one using app_resolver()
. In turn, each resolver adds a number of patterns using dmp_path()
. See these methods and _dmp_paths_for_app() in the source.
You can disable the automatic registration of apps with DMP by removing the include('', 'django_mako_plus')
line from urls.py
. With this line removed, DMP won’t inject any convention-based patterns into your project.
Project Patterns¶
Per Django best practices, we’ll split the patterns into a main include for the app and another file for the app. First modify your project URL file: mysite/urls.py
:
from django.apps import apps
from django.conf.urls import url, include
from django.views.static import serve
import os
urlpatterns = [
# DMP's JS file (for DEBUG mode)
url(
r'^django_mako_plus/(?P<path>[^/]+)',
serve,
{ 'document_root': os.path.join(apps.get_app_config('django_mako_plus').path, 'webroot') },
name='DMP webroot (for devel)',
),
# include the homepage app urls.py file
url('^homepage/?', include('homepage.urls')),
]
Patterns for the homepage
App¶
Create an app-specific file for the homepage app: homepage/urls.py
. These patterns are adapted from DMP’s default urls.py file. Each call to dmp_path
includes the four routing variables in either the pattern or the kwargs.
from django_mako_plus import dmp_path
urlpatterns = [
# Because these patterns are subpatterns within the app's resolver,
# we don't include the /app/ in the pattern -- it's already been
# handled by the app's resolver.
#
# Also note how the each pattern below defines the four kwargs--
# either as 1) a regex named group or 2) in kwargs.
dmp_path(
r'^(?P<userid>[0-9-]+)/(?P<dmp_page>[_a-zA-Z0-9\-]+)\.(?P<dmp_function>[_a-zA-Z0-9\.\-]+)/(?P<dmp_urlparams>.+?)/?$',
{ 'dmp_app': 'homepage' },
name='/homepage/userid/page.function/urlparams',
),
dmp_path(
r'^(?P<userid>[0-9-]+)/(?P<dmp_page>[_a-zA-Z0-9\-]+)\.(?P<dmp_function>[_a-zA-Z0-9\.\-]+)/?$',
{ 'dmp_app': 'homepage',
'dmp_urlparams': '' },
name='/homepage/userid/page.function',
),
dmp_path(
r'^(?P<userid>[0-9-]+)/(?P<dmp_page>[_a-zA-Z0-9\-]+)/(?P<dmp_urlparams>.+?)/?$',
{ 'dmp_app': 'homepage',
'dmp_function': 'process_request' },
'/homepage/userid/page/urlparams',
),
dmp_path(
r'^(?P<userid>[0-9-]+)/(?P<dmp_page>[_a-zA-Z0-9\-]+)/?$',
{ 'dmp_app': 'homepage',
'dmp_function': 'process_request',
'dmp_urlparams': '' },
name='/homepage/userid/page',
),
dmp_path(
r'^(?P<userid>[0-9-]+)/?$',
{ 'dmp_app': 'homepage',
'dmp_page': 'index',
'dmp_function': 'process_request',
'dmp_urlparams': '' },
name='/homepage/userid',
),
]
The userid
group in the patterns above accepts any number, plus a dash. The dash is the DMP value for “empty”. Our pattern could actually be improved, but it’ll work for this example.
View Function¶
Your view function needs to change because we have an additional named group in our patternns: userid
. We’ll have DMP convert this parameter to an int, with a default value of 0.
from django.http import HttpResponse
from django_mako_plus import view_function
@view_function
def process_request(request, userid:0=None):
return HttpResponse('The userid was %s' % userid)
All view functions in the homepage
need this function signature.
Test with the following urls:
Next Steps¶
We haven’t added any patterns for the default app. If homepage
is our default app, we need additional patterns in the main urls.py
file that don’t have an app.


T
- Return typepublic interface ExpressionVisitor<T>
| Modifier and Type | Method and Description |
|---|---|
T |
visitAlias(String aliasName)
Called for each traversed
Alias expression |
T |
visitBinaryOperator(BinaryOperatorKind operator,
T left,
T right)
Called for each traversed
Binary expression |
T |
visitEnum(EdmEnumType type,
List<String> enumValues)
Called for each traversed
Enumeration expression |
T |
visitLambdaExpression(String lambdaFunction,
String lambdaVariable,
Expression expression)
Called for each traversed lambda expression
|
T |
visitLambdaReference(String variableName)
Called for each traversed
LambdaRef |
T |
visitLiteral(Literal literal)
Called for each traversed
Literal expression |
T |
visitMember(Member member)
Called for each traversed
Member expression |
T |
visitMethodCall(MethodKind methodCall,
List<T> parameters)
Called for each traversed
Method expression |
T |
visitTypeLiteral(EdmType type)
Called for each traversed
TypeLiteral expression |
T |
visitUnaryOperator(UnaryOperatorKind operator,
T operand)
Called for each traversed
Unary expression |
T visitBinaryOperator(BinaryOperatorKind operator, T left, T right) throws ExpressionVisitException, ODataApplicationException
Binary
expressionoperator
- Operator kindleft
- Application return value of left sub treeright
- Application return value of right sub treeExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationT visitUnaryOperator(UnaryOperatorKind operator, T operand) throws ExpressionVisitException, ODataApplicationException
Unary
expressionoperator
- Operator kindoperand
- return value of sub treeExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationT visitMethodCall(MethodKind methodCall, List<T> parameters) throws ExpressionVisitException, ODataApplicationException
Method
expressionmethodCall
- Methodparameters
- List of application return values created by visiting each method parameterExpressionVisitException
- Thrown if an exception while traversing occurredODataApplicationException
- Thrown by the applicationT visitLambdaExpression(String lambdaFunction, String lambdaVariable, Expression expression) throws ExpressionVisitException, ODataApplicationException
lambdaFunction
- "ALL" or "ANY"lambdaVariable
- Variable name used lambda variableexpression
- Lambda expressionExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationT visitLiteral(Literal literal) throws ExpressionVisitException, ODataApplicationException
Literal
expressionliteral
- LiteralExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationT visitMember(Member member) throws ExpressionVisitException, ODataApplicationException
Member
expressionmember
- UriInfoResource object describing the whole path used to access an data value
(this includes for example the usage of $root and $it inside the URI)ExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationT visitAlias(String aliasName) throws ExpressionVisitException, ODataApplicationException
Alias
expressionaliasName
- Name of the aliasExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationT visitTypeLiteral(EdmType type) throws ExpressionVisitException, ODataApplicationException
TypeLiteral
expressiontype
- EdmTypeExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationT visitLambdaReference(String variableName) throws ExpressionVisitException, ODataApplicationException
LambdaRef
variableName
- Name of the used lambda variableExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationT visitEnum(EdmEnumType type, List<String> enumValues) throws ExpressionVisitException, ODataApplicationException
Enumeration
expressiontype
- Type used in the URI before the enumeration valuesenumValues
- List of enumeration valuesExpressionVisitException
- Thrown if an exception while traversing occuredODataApplicationException
- Thrown by the applicationCopyright © 2013–2018 The Apache Software Foundation. All rights reserved.


{% extends 'anonbase.html' %} {% block content %} Your registration is now complete. You will receive an email shortly with your activation code. {% endblock content %}


Seok Hyun Jin
email: sj372 at cornell dot edu
My name is Seok Hyun Jin, but I just go by
Jin.
I'm a software engineer working for
Amazon. I'm currently working in
Amazon Prime Air, a drone-based delivery system.
Previously, I worked for
Amazon Web Services.
I worked on launching two ML products under
Amazon A.I.:
Amazon Comprehend and
Amazon Translate.
Also, I briefly worked for
AWS IoT Greengrass.
In 2016, I finished my studies in
Computer Science at Cornell University
with a Bachelor's and a Master's degree.
For about 3 years, I was actively involved in research in areas of
Machine Learning, Robot Learning, and Social Computing.
I was a research assistant under
Prof. Ashutosh Saxena
at
the
Cornell Robot Learning Lab
working on the
Robobarista
project,
which uses deep learning to enable robots to manipulate novel objects.
I also did research under
Prof. David Mimno
on the
Chinese Voting Process project,
which models online social behavior using
probabilistic methods.
Also, I served as a teaching assistant for machine learning courses taught by
Prof. Thorsten Joachims
(2014) and
Prof. Kilian Weinberger
(2015).
Publications
Conference:
-
Moontae Lee, Seok Hyun Jin, David Mimno.
"Beyond Exchangeability: The Chinese Voting Process".
In Neural Information Processing Systems (NIPS), 2016,
Barcelona, Spain.
Full Oral (Acceptance rate: 46 / 2500 ~ 1.84%)
[Details]
[PDF]
[arXiv]
-
Jaeyong Sung, Seok Hyun Jin, Ashutosh Saxena.
"Robobarista: Object Part-based Transfer of Manipulation Trajectories from Crowd-sourcing in 3D Pointclouds".
In International Symposium on Robotics Research (ISRR), 2015.
[Details]
[PDF]
[arXiv]
Journal:
-
Jaeyong Sung, Seok Hyun Jin, Ian Lenz, Ashutosh Saxena.
"Robobarista: Learning to Manipulate Novel Objects via Deep Multimodal Embedding".
Status: Under review for International Journal of Robotics Research (IJRR).
[Details]
[PDF]
[arXiv]
Workshop:
-
Moontae Lee, Seok Hyun Jin, David Mimno.
"The Chinese Voting Process: The Evolution of Online Helpfulness Evaluations in Product Reviews and Question Answers".
In Proceedings of the 12th INFORMS Workshop on Data Mining and Decision Analytics, Houston, Texas.
Selected for Oral Presentations.
[Details]
[PDF]
-
Jaeyong Sung, Seok Hyun Jin, Ashutosh Saxena.
"Robobarista: Object Part-based Transfer of Manipulation Trajectories from Crowd-sourcing in 3D Pointclouds".
In AAAI-RSS Special Workshop on the 50th Anniversary of Shakey at RSS, 2015.
(
Won 50-years of Shakey Blue Sky Ideas Award
)
[Details]
Others:
-
Jaeyong Sung, Ian Lenz, Seok Hyun Jin, Ashutosh Saxena.
"Robobarista: Learning to Manipulate Novel Objects via Deep Multimodal Embedding".
In BayLearn Symposium, 2015.
[Details]
[PDF (extended abstract)]


Popular Events
ANWESHA
'Anwesha', which gets its name from the Sanskrit metaphrase for ‘expedition’, is IIT Patna’s annual 3-day techno-cultural festival organised by the student community. The fest, which made its humble beginnings in the year 2010 as an intra-college festival with only a few dozen events, has today grown into one of the biggest and most eagerly awaited youth festivals of the region. Anwesha today is a conglomeration of events that draw from diverse disciplines, ranging from the engineering sciences to the visual & performing arts.
For the latest news and updates about ‘Anwesha’, please visit the student-run portals listed below. The views/ opinions expressed at the links belong solely to the authors and may not necessarily represent the views of the Indian Institute of Technology Patna.
Official website: www.anwesha.info
Facebook page: www.facebook.com/anwesha.iitpatna
YouTube Channel: www.youtube.com/user/AnweshaIITP
CELESTA
Indian Institute of technology Patna each year celebrates its Technical Fest, christened as ''CELESTA'. This is a great beginning, which strives to inculcate interest in young minds to pursue technology and make it their passion.
For the latest news and updates about ‘Celesta’, please visit the student-run portals listed below. The views/ opinions expressed at the links belong solely to the authors and may not necessarily represent the views of the Indian Institute of Technology Patna
Facebook page: www.facebook.com/CelestaIITP
REVERBERANCE
It was started in 2008 and since then it has gained unmatched popularity. It is a cultural celebration held around 'Diwali'. Beautiful decoration through lights added with fantastic cultural performances makes IIT Patna really reverberate with joy during the ‘Reverberance’.
For the latest news and updates about ‘Reverberance’, please visit the student-run portals listed below. The views/ opinions expressed at the links belong solely to the authors and may not necessarily represent the views of the Indian Institute of Technology Patna
Facebook page: www.facebook.com/iitp.sociocultural
SPORTS EVENTS
The Students' Gymkhana Building, situated in the IIT Patna hostel compound, has a synthetic badminton court and a gymnasium. In addition, the students have access to a basketball court, a volleyball court, table tennis tables and a football-cum-cricket ground within the transit campus. State-of-the-art facilities for all sports are planned at IIT Patna’s main campus in Bihita.
For the latest news and updates about ‘Sports Events’, please visit the student-run portals listed below. The views/ opinions expressed at the links belong solely to the authors and may not necessarily represent the views of the Indian Institute of Technology Patna
Facebook page: www.facebook.com/SportsIITPatna
Badminton
Rocketing smashes and precise serves fill up the badminton court with extreme action, nervousness and most importantly fun. Badminton is one of the most popular recreational activity for all ages and is extremely popular in all ages. it is one of the few games that can be played at any time, and in any weather. IIT Patna`s badminton court never fail to find able players all round the year. A lot of people play badminton for fitness and some love the leisure. The inter-department badminton competition searches for the best players in all the departments who fight the battle to become the ultimate winner of raquets. The competition gets the huge participation and audiences and the best players get the opportunity to represent the institute in inter-IIT sports meet.
PPL (Patna Premier League)
The two most inseparable words "Cricket and India" have found another equally inseparable pair "PPL and IIT Patna". Originally started in 2009 it sprang up as a much celebrated tournament of IIT Patna. The thrill and competition which the event had witnessed has grown enormously during the recent years and could be clearly seen in the fifth edition this year. Whether it be the "Pythons" taking on the "Bolts" or the "Invincibles" taking on the "Falcons" every match has witnessed the enormous talent which the players had displayed.
Thus PPL league provides the platform for players to display their talents and improve their skills thereby achieving the purpose for which it was established as well as providing a break from the strenuous curriculum and helping in the all-round development of the individual.
BasketBall
This sweat-flooded, hormone-active game is tested to its limits only from Inter-department basketball matches. There's heavy action,awe-inspiring tackles, bulls eye aiming, winning strategies and lots more. In the recent tournament, the computer science branch was the winner, owing to its high spirited engineers, showing a breathtaking display of team spirit and sportsmanship.
May this fever of basketball remain in the hearts of engineers!


|
Proposed B-Tree Library |
|
Warning: The implementation is at a beta stage.
The library should only be used by those willing to assume the risks of beta software. |
Introduction
The proposed Boost B-tree library provides associative
containers that are resident on some form of random access external memory,
such as a hard-disk, solid-state disk, or USB memory-stick.. B-trees perform well on hardware ranging
from ancient floppy disk drives up to humongous hard-drive arrays. B-trees are the technology behind
many or even most high-performance disk file-systems and
disk-resident databases.
|
The B in "B-tree" does
not stand for "Binary"
The origin of "B-tree" has never been explained by the
authors [Rudolf Bayer and
Edward McCreight]. As
we shall see, "balanced," "broad," or "bushy" might apply.
Others suggest that the "B" stands for Boeing [their employer]. Because of
his contributions, however, it seems appropriate to think
of B-trees as "Bayer"-trees.
Douglas Comer,
The Ubiquitous B-Tree,
Computing Surveys, Vol. 11, No. 2, June 1979
|
Library Characteristics
- The interface and behavior is similar, but not identical, to the C++
Standard Library's
map
, multimap
, set
,
and multiset
. Differences include:
- Types supplied by the
Key
and
T
template parameters must be copyable via
std::memcpy
and must not contain pointers or references.
- Interfaces traffic in
const_iterator
. Maps provide a
writable()
function that turns a const_iterator into an
iterator.
insert()
, emplace()
, and erase()
invalidate iterators.
- No
operator[]
or at
functions supplied.
Returning references to data that can be swapped out even by const
functions is too dangerous.
- Additional classes provide indexes
into a flat file.
- Variable length data can be accommodated. Strings are supported via the
new standard library TS
string_view
class which provides the
familiar std::string
interface. A version of the TS
string_view
class is provided, so things like
my_map.emplace("FWIW", "For what its worth");
work out of the box.
- Very large data elements are not a problem. Because B-trees are most
efficient when value types are very small relative to the hardware's natural
page size (4096 for most current hard disks), a pure B-tree slows
dramatically if given value types even a few hundred bytes in length, let
alone much larger sizes. Using a B-tree as an index into a flat file that
actually contains the data has long been the preferred solution.
- A single flat file can be indexed by as many indexes as desired. Thus a
customer record can be indexed by account-number, name, and so forth.
- Runtime options allow performance tuning:
- Page size allows hardware specific tuning at file creation time.
- Cache size allows control over speed versus program memory tradeoff.
- Preload option allows control over speed versus operating system disk cache
memory tradeoff.
- Hints ease task of performance tuning.
- Traits allow users to specify internal types:
- Endian types are used by default to ensure portable files. Prepackaged big, little,
and native endian traits are supplied.
- User defined traits can be supplied to support specific needs.
- The specific B-tree form used is the B+ tree. Modifications to the classic B+ tree
include:
- New-node-on-full (i.e. lazy) rather than split-on-full for ordered inserts.
Benefits include ability to pack a B-Tree for 100% disk and memory space
utilization and, as a result, faster operation.
- Free-at-empty (i.e. lazy) rather than rebalancing
erases. See the Sen/Tarjan
paper
for discussion of rationale.
- The disk file includes meta information about the
tree, including user supplied information.
- Currently implemented in C++03. Tests pass in recent versions of GCC on
Linux, OS X, and Windows, VC++ on Windows, and Clang on OS X.
Coming Soon
- A bulk load option that generates packed trees. Fastest way to load
large datasets.
Wish List
- Utility functionality such as
btpack
,
btinfo
, and btrecover
to meet
administrative needs.
- Concurrent use by other processes is a
high priority for the future.
- Multiple B-trees in one file. Requested by Cory Nelson. Possible design:
Initial btree_map in the file is an index of its children. Key: name, Data:
page id of the child's header page. Recursion allowed; the header page
pointed could itself be an index header. Current interface might gain
additional constructor and open() overload taking a ref to the parent index
and the desired name.
- Memory mapped file based B-tree. Requested by Cory Nelson "for small
B-trees or large address spaces". The flat files indexed by the index
classes already use memory mapped files.
- C++11 features.
History of the library
A PL/1 language B-tree library was developed by the author about 1982. It
was redone in C in 1984, and has been in continuous use in industrial
applications since then. It was based on a single cursor model rather than an
iterator model. Although the Boost library is a new design and is implemented
with all new code, the predecessor library provided the experience that taught
me about B-trees in general, and the specifics of what is needed and what
isn't.
Designs paths not taken
Based on prior experience including actual implementation and use, several
features described in the literature are not included:
- Key prefix compression. All the keys on a page may have the same
value for their initial bytes. Particularly on branches, this prefix could
be stored only once, saving space and allowing more entries per page, and in
turn that could speed searches. The added complexity is considerable, and
the increased computational burden tends to result in slower rather than
faster operations. Might be worth considering in the future for variable
length keys only; they already have to provide some of the needed machinery.
The C predecessor library abandoned this approach early on because it didn't
actually speed up applications in practice.
- Key computation on branch pages. The keys stored on branch pages need
not be full length, as long as the ordering is maintained. Thus for a branch
key separating pointers to pages with last key "ALPHA" and first key "BETA",
respectively, it is sufficient to store "B" as the branch key rather than
"BETA". Although the C predecessor library still uses computed branch keys
if keys are variable length, it has been a source of hard to track down
bugs, and doesn't support deletion properly to this day.
- Bidirectional page sequence list. Adds page space overhead and
insert/erase program complexity. Doing an inverted tree walk to the prior or next
page during traversal is simple and effective.
Bibliography
Rudolf Bayer and Edward M. McCreight,
Organization and Maintenance of Large Ordered Indexes,
Acta Informatica, 1:173-189, 1972. The original publication is
still a good starting point to understand the B-tree.
Douglas Comer,
The
Ubiquitous B-Tree, ACM Computing Surveys, Vol. 11, No. 2,
June, 1979. Covers many variations and implementation techniques,
with their trade-offs.
Siddhartha Sen and Robert E. Tarjan, Deletion
Without Rebalancing in Multiway Search Trees, Proc. 20th
International Symposium on Algorithms and Computation (ISAAC),
December 2009. Explanation of why free-at-empty is better than
rebalancing.
Acknowledgements
Zach Laine provided several enhancements and bug fixes. Support
for turning the prototype implementation into a finished library was provided
by the Naval Postgraduate School, Monterey, California.
Revised
03 September 2013
© Copyright Beman Dawes, 2010, 2013
Distributed under the Boost Software License, Version 1.0. See
www.boost.org/LICENSE_1_0.txt


Try This
import turtle t = turtle.Turtle() # Get side length for user and make sure its between 2 and 25 sides = int(input("Please enter the number of sides you would like between 3 and 24: ")) while sides < 3 or sides > 24: sides = int(input("Please enter the number of sides you would like between 3 and 24: ")) # Getting rid of magic numbers totalAngle = 180 sideSubtraction = 2 lineLength = 20 rotation = totalAngle - (((sides - sideSubtraction)*totalAngle)/sides) # Made color list colors = ['red', 'darkred', 'darkorchid', 'orange', 'coral', 'cornsilk', 'yellow', 'green', 'darkgreen', 'blue', 'cyan', 'aqua', 'aquamarine', 'darkturquoise', 'blueviolet', 'purple', 'pink', 'black', 'chocolate', 'gray', 'darkgray', 'beige', 'brown', "chartreuse"] # Makes pologyon with requested number of sides in different colors for number in range(sides): t.color(colors[number]) t.forward(lineLength) t.left(rotation)
Run


Christmas is coming! Dive into celebrations by visiting all the best holiday-related points of interest in your town. To view all attractions on the map, just go to Configure map menu - POI and select "Christmas".
You'll see 5 types of POI:
Hint to mappers: add more Xmas objects to the map to help people enjoy the holiday even more!
Ready to add Christmas-related POI to the map? There are some simple rules that will help you do that the best way possible. Tag the location, and do not forget about other details like the date when the attraction will be working. Follow the link to view a detailed guide to mapping Christmas POI. You'll also find a clear template there.
Remember, you can add POI to the map without leaving the app! Just to Plugins menu to activate the 'OSM editing' plugin, then return to the map, make a long press on a certain point and select 'Create POI'. Then you'll have to switch to the Advanced tab, enter the name of the POI and select its type (for example, Christmas tree) below the 'Name' line. After that, you'll be able to add any tags using the button 'Add tag'. For instance, you can write the tag 'xmas:feature' and in the 'value' field write 'tree'. This way, the people searching for Christmas trees nearby will see this one, as well.
Have questions? You can always contact us at<EMAIL_ADDRESS>or join the discussion on OsmAnd's forum.


DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON https://guides.rubyonrails.org.
API Documentation Guidelines
This guide documents the Ruby on Rails
API documentation guidelines.
After reading this guide, you will know:
- How to write effective prose for documentation purposes.
- Style guidelines for documenting different kinds of Ruby code.
RDoc
The Rails API documentation is generated with
RDoc. To generate it, make sure you are
in the rails root directory, run bundle install
and execute:
$ bundle exec rake rdoc
Resulting HTML files can be found in the ./doc/rdoc directory.
Please consult the RDoc documentation for help with the markup, and also take into account these additional directives.
Links
Rails API documentation are not meant to be viewed on GitHub and therefore links should use the RDoc link
markup relative to the current API.
This is due to differences between GitHub Markdown and the generated RDoc that is published at api.rubyonrails.org and edgeapi.rubyonrails.org.
For example, we use [link:classes/ActiveRecord/Base.html]
to create a link to the ::ActiveRecord::Base
class generated by RDoc.
This is preferred over absolute URLs such as [https://api.rubyonrails.org/classes/ActiveRecord/Base.html]
, which would take the reader outside their current documentation version (e.g. edgeapi.rubyonrails.org).
Wording
Write simple, declarative sentences. Brevity is a plus: get to the point.
Write in present tense: "Returns a hash that...", rather than "Returned a hash that..." or "Will return a hash that...".
Start comments in upper case. Follow regular punctuation rules:
# Declares an attribute reader backed by an internally-named
# instance variable.
def attr_internal_reader(*attrs)
# ...
end
Communicate to the reader the current way of doing things, both explicitly and implicitly. Use the idioms recommended in edge. Reorder sections to emphasize favored approaches if needed, etc. The documentation should be a model for best practices and canonical, modern Rails usage.
Documentation has to be brief but comprehensive. Explore and document edge cases. What happens if a module is anonymous? What if a collection is empty? What if an argument is nil?
The proper names of Rails components have a space in between the words, like "Active Support". ActiveRecord
is a Ruby module, whereas Active Record is an ORM. All Rails documentation should consistently refer to Rails components by their proper names.
Spell names correctly: Arel, minitest, RSpec, HTML, MySQL, JavaScript, ERB, Hotwire. When in doubt, please have a look at some authoritative source like their official documentation.
Use the article "an" for "SQL", as in "an SQL statement". Also "an SQLite database".
Prefer wordings that avoid "you"s and "your"s. For example, instead of
If you need to use `return` statements in your callbacks, it is recommended that you explicitly define them as methods.
use this style:
If `return` is needed, it is recommended to explicitly define a method.
That said, when using pronouns in reference to a hypothetical person, such as "a user with a session cookie", gender neutral pronouns (they/their/them) should be used. Instead of:
- he or she... use they.
- him or her... use them.
- his or her... use their.
- his or hers... use theirs.
- himself or herself... use themselves.
English
Please use American English (color, center, modularize, etc). See a list of American and British English spelling differences here.
Oxford Comma
Please use the Oxford comma ("red, white, and blue", instead of "red, white and blue").
Example Code
Choose meaningful examples that depict and cover the basics as well as interesting points or gotchas.
Use two spaces to indent chunks of code--that is, for markup purposes, two spaces with respect to the left margin. The examples themselves should use Rails coding conventions.
Short docs do not need an explicit "Examples" label to introduce snippets; they just follow paragraphs:
# Converts a collection of elements into a formatted string by
# calling to_s on all elements and joining them.
#
# Blog.all.to_fs # => "First PostSecond PostThird Post"
On the other hand, big chunks of structured documentation may have a separate "Examples" section:
# ==== Examples
#
# Person.exists?(5)
# Person.exists?('5')
# Person.exists?(name: "David")
# Person.exists?(['name LIKE ?', "%#{query}%"])
The results of expressions follow them and are introduced by "# => ", vertically aligned:
# For checking if an integer is even or odd.
#
# 1.even? # => false
# 1.odd? # => true
# 2.even? # => true
# 2.odd? # => false
If a line is too long, the comment may be placed on the next line:
# label(:article, :title)
# # => Title
#
# label(:article, :title, "A short title")
# # => A short title
#
# label(:article, :title, "A short title", class: "title_label")
# # => A short title
Avoid using any printing methods like puts
or p
for that purpose.
On the other hand, regular comments do not use an arrow:
# polymorphic_url(record) # same as comment_url(record)
Booleans
In predicates and flags prefer documenting boolean semantics over exact values.
When "true" or "false" are used as defined in Ruby use regular font. The
singletons true
and false
need fixed-width font. Please avoid terms like
"truthy", Ruby defines what is true and false in the language, and thus those
words have a technical meaning and need no substitutes.
As a rule of thumb, do not document singletons unless absolutely necessary. That
prevents artificial constructs like !!
or ternaries, allows refactors, and the
code does not need to rely on the exact values returned by methods being called
in the implementation.
For example:
`config.action_mailer.perform_deliveries` specifies whether mail will actually be delivered and is true by default
the user does not need to know which is the actual default value of the flag, and so we only document its boolean semantics.
An example with a predicate:
# Returns true if the collection is empty.
#
# If the collection has been loaded
# it is equivalent to <tt>collection.size.zero?</tt>. If the
# collection has not been loaded, it is equivalent to
# <tt>!collection.exists?</tt>. If the collection has not already been
# loaded and you are going to fetch the records anyway it is better to
# check <tt>collection.length.zero?</tt>.
def empty?
if loaded?
size.zero?
else
@target.blank? && !scope.exists?
end
end
The API is careful not to commit to any particular value, the method has predicate semantics, that's enough.
File Names
As a rule of thumb, use filenames relative to the application root:
config/routes.rb # YES
routes.rb # NO
RAILS_ROOT/config/routes.rb # NO
Fonts
Fixed-width Font
Use fixed-width fonts for:
- Constants, in particular class and module names.
- Method names.
- Literals like
nil
,false
,true
,self
. - Symbols.
- Method parameters.
- File names.
class Array
# Calls to_param on all its elements and joins the result with
# slashes. This is used by url_for in Action Pack.
def to_param
collect { |e| e.to_param }.join '/'
end
end
WARNING: Using +...+
for fixed-width font only works with simple content like
ordinary method names, symbols, paths (with forward slashes), etc. Please use
<tt>...</tt>
for everything else, notably class or module names with a
namespace as in {ActiveRecord::Base}
.
You can quickly test the RDoc output with the following command:
$ echo ":to_param" | rdoc --pipe
# =>
:to_param

Regular Font
When "true" and "false" are English words rather than Ruby keywords use a regular font:
# Runs all the validations within the specified context.
# Returns true if no errors are found, false otherwise.
#
# If the argument is false (default is nil), the context is
# set to <tt>:create</tt> if <tt>new_record?</tt> is true,
# and to <tt>:update</tt> if it is not.
#
# Validations with no <tt>:on</tt> option will run no
# matter the context. Validations with # some <tt>:on</tt>
# option will only run in the specified context.
def valid?(context = nil)
# ...
end
Description Lists
In lists of options, parameters, etc. use a hyphen between the item and its description (reads better than a colon because normally options are symbols):
# * <tt>:allow_nil</tt> - Skip validation if attribute is nil.
The description starts in upper case and ends with a full stop—it's standard English.
Dynamically Generated Methods
Methods created with (module|class)_eval(STRING)
have a comment by their side with an instance of the generated code. That comment is 2 spaces away from the template:
for severity in Severity.constants
class_eval <<-EOT, __FILE__, __LINE__ + 1
def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block)
add(#{severity}, message, progname, &block) # add(DEBUG, message, progname, &block)
end # end
#
def #{severity.downcase}? # def debug?
#{severity} >= @level # DEBUG >= @level
end # end
EOT
end
If the resulting lines are too wide, say 200 columns or more, put the comment above the call:
# def self.find_by_login_and_activated(*args)
# options = args.extract_options!
# ...
# end
self.class_eval %{
def self.#{method_id}(*args)
options = args.extract_options!
#...
end
}
Method Visibility
When writing documentation for Rails, it's important to understand the difference between public user-facing API vs internal API.
Rails, like most libraries, uses the private keyword from Ruby for defining internal API. However, public API follows a slightly different convention. Instead of assuming all public methods are designed for user consumption, Rails uses the :nodoc:
directive to annotate these kinds of methods as internal API.
This means that there are methods in Rails with public
visibility that aren't meant for user consumption.
An example of this is ActiveRecord::Core::ClassMethods#arel_table:
module ActiveRecord::Core::ClassMethods
def arel_table # :nodoc:
# do some magic..
end
end
If you thought, "this method looks like a public class method for ::ActiveRecord::Core
", you were right. But actually the Rails team doesn't want users to rely on this method. So they mark it as :nodoc:
and it's removed from public documentation. The reasoning behind this is to allow the team to change these methods according to their internal needs across releases as they see fit. The name of this method could change, or the return value, or this entire class may disappear; there's no guarantee and so you shouldn't depend on this API in your plugins or applications. Otherwise, you risk your app or gem breaking when you upgrade to a newer release of Rails.
As a contributor, it's important to think about whether this API is meant for end-user consumption. The Rails team is committed to not making any breaking changes to public API across releases without going through a full deprecation cycle. It's recommended that you :nodoc:
any of your internal methods/classes unless they're already private (meaning visibility), in which case it's internal by default. Once the API stabilizes the visibility can change, but changing public API is much harder due to backwards compatibility.
A class or module is marked with :nodoc:
to indicate that all methods are internal API and should never be used directly.
To summarize, the Rails team uses :nodoc:
to mark publicly visible methods and classes for internal use; changes to the visibility of API should be considered carefully and discussed over a pull request first.
Regarding the Rails Stack
When documenting parts of Rails API, it's important to remember all of the pieces that go into the Rails stack.
This means that behavior may change depending on the scope or context of the method or class you're trying to document.
In various places there is different behavior when you take the entire stack into account, one such example is ActionView::Helpers::AssetTagHelper#image_tag:
# image_tag("icon.png")
# # =>
Although the default behavior for #image_tag
is to always return
/images/icon.png
, we take into account the full Rails stack (including the
Asset Pipeline) we may see the result seen above.
We're only concerned with the behavior experienced when using the full default Rails stack.
In this case, we want to document the behavior of the framework, and not just this specific method.
If you have a question on how the Rails team handles certain API, don't hesitate to open a ticket or send a patch to the issue tracker.


Thanks to everyone that race or volunteered. These are about as
final as they are going to get. If you have any problems or changes, please
email me ar<EMAIL_ADDRESS>The Tim Murphy State Farm Montana Team Championship Trophy will be up for grabs
again next year at the state championships, whoever hosts them. You can view
the trophy at Glacier Cyclery in Whitefish. Special thanks to Glacier Cyclery www.glaciercyclery.com
and the really Big Mountain www.skiwhitefish.com for providing
mechanical support, timing and a great venue for the BBQ/Awards.
Thanks,
Russ Schneider
Flathead Cycling
|
MBRA Number |
First Name |
Last Name |
Club |
USCF Category |
Time |
|
|
|
Men 1 / 2 |
|
|
|
|
|
|
1 |
12 |
Clint |
Muhlfeld |
Flathead Cycling |
2 |
2:55:15 |
|
2 |
1 |
Scott |
Herzig |
|
2 |
2:55:15 |
|
3 |
56 |
Evan |
|
Hammer Gel |
2 |
2:57:25 |
|
4 |
57 |
Joe |
Arnone |
Hammer Gel |
2 |
2:57:26 |
|
5 |
15 |
Josh |
Tack |
Five Valley Velo |
2 |
2:57:45 |
|
6 |
13 |
John |
Weyhrich |
Five Valley Velo |
2 |
3:00:10 |
|
7 |
48 |
Chance |
Cooke |
Flathead Cycling |
2 |
3:21:40 |
|
|
|
|
|
|
|
|
|
King of the Mountains |
|
|
|
|
|
|
|
|
|
Evan Lawrence |
|
Hammer Gel |
|
|
|
Sprint 1 Men 1, 2, 3 |
|
|
|
|
|
|
|
|
|
Joe Arnone |
|
Hammer Gel |
|
|
|
Sprint 2 Men 1, 2, 3 |
|
|
|
|
|
|
|
|
|
John Wehyrich |
|
Five Valley Velo |
|
|
|
|
|
|
|
|
|
|
|
|
Men 3 |
|
|
|
|
|
|
1 |
325 |
Alex |
Lassier |
GAS/Heritage Homes |
3 |
3:00:10 |
|
2 |
315 |
Bob |
Presta |
Five Valley Velo |
3 |
3:00:10 |
|
3 |
324 |
Erik |
Bailly |
GAS/Heritage Homes |
3 |
3:00:10 |
|
4 |
175 |
Eric |
Greenberg |
Flathead Cycling |
3 |
3:00:10 |
|
5 |
316 |
Brad |
Morgan |
GAS/Heritage Homes |
3 |
3:00:10 |
|
6 |
326 |
Shane |
Mundt |
|
3 |
3:00:10 |
|
7 |
410 |
Ben |
Sullivan |
|
3 |
3:00:10 |
|
8 |
317 |
Aaron |
Johnson |
GAS/Heritage Homes |
3 |
3:11:00 |
|
9 |
454 |
John |
Lackey |
GAS/Heritage Homes |
3 |
3:11:00 |
|
10 |
187 |
Tim |
Noonan |
Flathead Cycling |
3 |
DNF |
|
|
|
|
|
|
|
|
|
|
Men 4 / 5 |
|
|
|
|
|
|
1 |
436 |
Matt |
Butterfield |
Flathead Cycling |
4 |
2:15:15 |
|
2 |
34 |
Mike |
Windower |
Unattached |
4 |
2:15:15 |
|
3 |
3 |
Joe |
Chalners |
|
4 |
2:15:15 |
|
4 |
52 |
Graham |
Meng |
Five Valley Velo |
4 |
2:15:15 |
|
5 |
53 |
|
French |
Unattached |
4 |
2:15:15 |
|
6 |
422 |
Robert |
Funk |
|
4 |
2:15:15 |
|
7 |
455 |
Patrick |
Marzullo |
Five Valley Velo |
4 |
2:15:15 |
|
8 |
450 |
Marchall |
Opel |
|
Jun |
2:15:15 |
|
9 |
54 |
Ben |
Parsons |
Unattached |
4 |
2:15:30 |
|
10 |
430 |
David |
Hessinger |
Echelon |
4 |
2:18:00 |
|
11 |
431 |
Chris |
Rice |
GAS/Heritage Homes |
4 |
2:18:00 |
|
12 |
51 |
|
Piva |
|
4 |
DNF |
|
13 |
49 |
Zach |
Heskert |
Flathead Cycling |
Jun |
DNF |
|
|
|
|
|
|
|
|
|
|
Men Masters 40+ A |
|
|
|
|
|
|
1 |
205 |
David |
Landstrom |
Flathead Cycling |
40+ |
2:13:00 |
|
2 |
216 |
Scott |
Smith |
|
40+ |
2:13:00 |
|
3 |
184 |
Peter |
Ismert |
Sear/Dr. Horton |
40+ |
2:13:00 |
|
4 |
7 |
Rich |
|
Flathead Cycling |
40+ |
2:13:00 |
|
5 |
210 |
Jeff |
Agemenon |
Echelon |
40+ |
2:13:00 |
|
6 |
248 |
John |
Coulthard |
|
40+ |
2:18:31 |
|
7 |
201 |
Rich |
West |
Echelon |
40+ |
2:18:31 |
|
|
|
|
|
|
|
|
|
|
Men Masters 40+ B |
|
|
|
|
|
|
1 |
179 |
Frank |
Gonzalez |
|
40+ |
2:13:00 |
|
2 |
182 |
Bob |
Foley |
Flathead Cycling |
40+ |
2:13:00 |
|
3 |
178 |
Jeremy |
Oury |
Five Valley Velo |
40+ |
2:15:35 |
|
4 |
219 |
Jay |
Shaver |
Flathead Cycling |
40+ |
2:16:11 |
|
5 |
434 |
Albert |
Pendegrass |
|
40+ |
2:22:00 |
|
6 |
176 |
Brett |
Tallman |
Flathead Cycling |
40+ |
2:22:00 |
|
7 |
218 |
Jeff |
Olson |
|
40+ |
2:26:20 |
|
8 |
214 |
Blair |
Fisher |
|
40+ |
2:29:20 |
|
9 |
245 |
John |
Winnie |
|
40+ |
2:34:00 |
|
|
|
|
|
|
|
|
|
|
Men Masters 50+ |
|
|
|
|
|
|
1 |
244 |
Walt |
Chauner |
Flathead Cycling |
50+ |
2:13:00 |
|
2 |
217 |
Michael |
Longmire |
|
50+ |
2:13:00 |
|
3 |
183 |
Greg |
Rice |
Baddlands Cycling |
50+ |
2:15:35 |
|
4 |
181 |
Jeff |
Penrod |
Flathead Cycling |
50+ |
2:15:35 |
|
5 |
185 |
David |
Gorman |
Polson |
50+ |
2:15:35 |
|
6 |
180 |
|
Castren |
Rocky Mtn
Outfitters |
50+ |
2:31:20 |
|
7 |
135 |
Chuck |
Harris |
Flathead Cycling |
50+ |
DNF |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Women 1 / 2 / 3 |
|
|
|
|
|
|
1 |
121 |
Renee |
Coppock |
|
3 |
2:40:05 |
|
2 |
|
|
|
|
|
|
|
Queen of the Mountains Women
1,2,3,4,5 |
|
|
|
|
|
|
|
|
|
Renee Coppock |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Women 4 / 5 |
|
|
|
|
|
|
1 |
399 |
Jennifer |
Nerison |
Five Valley Velo |
4 |
2:40:05 |
|
2 |
55 |
Alison |
Forney |
Unattached |
5 |
2:42:10 |
|
3 |
22 |
Margaret |
Miller |
Flathead Cycling |
5 |
2:42:35 |
|
4 |
117 |
Rhonda |
Wodnik |
Great Divide Cycling |
4 |
2:42:45 |
|
5 |
120 |
Jane |
O'Driscoll |
Great Divide Cycling |
4 |
2:46:30 |
|
6 |
116 |
Andrea |
Thorpe |
Five Valley Velo |
4 |
2:55:59 |
|
7 |
177 |
Julianne |
Burkhardt |
Great Divide Cycling |
4 |
3:05:05 |
|
8 |
186 |
Dusty |
Hosek |
Flathead Cycling |
5 |
3:05:14 |
|
9 |
50 |
Melanie |
Toelcke |
Flathead Cycling |
5 |
DNF |
|
10 |
188 |
Kristen |
Fredricks |
Flathead Cycling |
5 |
DNF |
|
|
|
|
|
|
|
|
|
|
Men Juniors |
|
|
|
|
|
|
1 |
29 |
Jack |
Meng |
|
Jun |
2:46:20 |
|
2 |
30 |
Willy |
Zellner |
|
Jun |
1:15:00 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
|
|
|
Flathead Cycling |
|
99 pts |
|
2 |
|
|
|
Five Valley Velo |
|
53 pts |
|
3 |
|
|
|
GAS/Heritage Homes |
|
25 pts |
|
4 |
|
|
|
|
|
22 pts |
|
5 |
|
|
|
|
|
22 pts |
|
6 |
|
|
|
|
|
18 pts |
|
7 |
|
|
|
Hammer Gel |
|
15 pts |
|
8 |
|
|
|
|
|
13 pts |
|
9 |
|
|
|
Great Divide Cycling |
|
11 pts |
|
10 |
|
|
|
Echelon |
|
11 pts |
|
11 |
|
|
|
Sear/ Dr. Horton |
|
8 pts |
|
12 |
|
|
|
Baddlands |
|
8 pts |
|
13 |
|
|
|
|
|
5 pts |


{% extends "sidebar.html" %} {% block content %}
The HIV genome is annotated with genes, proteins, and RNA structures. The PCR fragments used for RNA amplification are also shown.


The name and version of the API to create (should be unique).
The resource this API will expose (will be used for CRUD or Publish API operations).
A JSON payload that will be used as first and reference resource of this API
{{ api.referencePayload }}


Signup Here
Invalid email and password.
You have been logged out.
Username
Password
Full Name
Sign Up
Sign In


Privacy Policy
We take your privacy very seriously and are committed to being transparent with how we use your information. This website, software, applications, and any services linked by this Privacy Policy are controlled by IFLS, Inc. (collectively “We” or “us”).
Our Privacy Policy explains:
- What information we collect and why we collect it.
- How we use that information.
- The choices we offer, including how to access and update information.
If you have any questions about this Privacy Policy, please contact us at<EMAIL_ADDRESS>.
Information we collect
We collect information to provide better services to our users and improve our business.
We collect information in two ways:
-
Information you give us or information provided through a social network. For example, some of our services require you to sign up for an account, provide information for a contest or award, or link an account through a social network. We work with social networks including, but not limited to Facebook, Twitter, Google Plus, and LinkedIn. We have access to information you directly provide and information through those social networking services based on your privacy settings on those networks.
-
Information we get from your use of our services. We may collect information about the services that you use and how you use them, like when you visit different parts of our site or applications and what selections you make on the services. We may also automatically collect certain technical information such as:
-
Device information
We may collect device-specific information (such as your hardware model, operating system version, unique device identifiers, and mobile information if you use a mobile device to access the site). -
Log information
When you use our services or view content provided by us, we may automatically collect and store certain information in server logs. This information may include:- details of how you used our service, such as your navigation paths and search queries.
- mobile related information if you access our website using your mobile device.
- internet protocol address.
- device event information such as crashes, system activity, hardware settings, browser type, browser language, the date and time of your request and referral URL.
- cookies that may uniquely identify your browser, mobile device, or your account.
- Browser type, operating system, and other technical information
-
How we use information we collect
We use the information we collect from all of our services to provide, maintain, protect and improve our services, to develop new services and offerings and to protect us and our users. We also use this information to offer you tailored content like giving you more relevant search results and ads.
When you contact us, we may keep a record of your communication as well as the other information in this Privacy Policy to help solve any issues you might be facing. We may use your email address to inform you about our services, such as letting you know about upcoming changes or improvements.
We use aggregated and demographic information to support our advertising needs so we can continue to provide many services for free. Your personally identifiable information is never disclosed to these parties, unless you are notified or consent.
Please keep in mind that comments sections, forums, and other similar areas of our services are public. Any information posted in those areas is viewable and usable by anyone that has access.
We will ask for your consent before using information for a purpose other than those that are set out in this Privacy Policy.
Choice
If we provide you with any mailings or other communication, you can always opt out of that communication.
You may also set your browser to block all cookies, including cookies associated with our services, or to indicate when a cookie is being set by us. However, it’s important to remember that many of our services may not function properly if your cookies are disabled.
You have the right to remove your personal information from our databases. To do this, please delete your Company account. If you have any problems or questions, please let us know by contacting us here<EMAIL_ADDRESS>and we will assist you with the process.
Accessing and updating your personal information
Whenever you use our services, we aim to provide you with access to your personal information in your account. If that information is wrong, we strive to give you ways to update it quickly or to delete it unless we have to keep that information for legitimate business or legal purposes. When updating your personal information, we may ask you to verify your identity before we can act on your request.
Do Not Track Signals
Some web browsers have settings that include “do not track signals.” Our services are not currently engineered to respond to those signals from browsers.
Information we share
We do not share personal information with companies, outside organizations and individuals unless one of the following circumstances apply:
-
With your consent
We will share personal information with companies, outside organizations or individuals if we have your consent to do so. -
For external processing
We provide personal information to our affiliates or other trusted businesses or persons to process it for us, based on our instructions and in compliance with our Privacy Policy and any other appropriate confidentiality and security measures. -
For legal reasons
We will share personal information with companies, outside organizations or individuals if we have a good-faith belief that access, use, preservation or disclosure of the information is reasonably necessary to meet any applicable law, regulation, legal process or enforceable governmental request, detect, prevent, or otherwise address fraud, security or technical issues or protect against harm to the rights, property or safety of our users or the public as required or permitted by law. -
In case of a sale or asset transfer
If we become involved in a merger, acquisition or other transaction involving the sale of some or all of our assets, user information, including personal information collected from you through your use of our services, could be included in the transferred assets. Should such an event occur, we will use reasonable means to notify you, either through email and/or a prominent notice on the services.
-
In aggregated form for business purposes
We may share aggregated, non-personally identifiable information publicly and with our partners we have a relationship with, advertisers or connected sites. For example, we may share information to show trends about the general use of our services.
Information security
We work hard to protect our users from unauthorized access to or unauthorized alteration, disclosure or destruction of information we hold however no website is entirely secure. You should protect the account information in your possession as well.
Third-Party Sites
Our Privacy Policy does not apply to services offered by other companies or individuals, including products or sites that may be displayed to you on this site. We also do not control the privacy policies and your privacy settings on third-party sites, including social networks.
Enforcement
We regularly review our compliance with our Privacy Policy. When we receive formal written complaints, we will contact the person who made the complaint to follow up.
Children Under 13
Our site is not directed toward children under 13 and we will not knowingly collect information for any child under the age of 13. If you are the parent of a child under the age of 13 and have a concern regarding your child’s information on our site, please contact us at<EMAIL_ADDRESS>Our Services are Located in the United States
Our website and associated services are hosted in the United States. If you are outside of the United States, your information will be processed and stored in the United States and you are consenting to such processing and storage.
Changes
Our Privacy Policy may change from time to time. We will post any privacy policy changes on this page and, if the changes are significant, we will provide a more prominent notice (including, for certain services, email notification of privacy policy changes).
This Privacy Policy was last updated on August 5th, 2014.


THE DEVIL'S OWN A film review by James Berardinelli Copyright 1997 James Berardinelli
RATING (0 TO 10): 6.0 Alternative Scale: **1/2 out of ****
United States, 1997 U.S. Release Date: 3/26/97 (wide) Running Length: 1:51 MPAA Classification: R (Violence, profanity) Theatrical Aspect Ratio: 2.35:1
Cast: Harrison Ford, Brad Pitt, Margaret Colin, Ruben Blades,=20 Treat Williams, George Hearn, Natascha McElhone Director: Alan J. Pakula Producers: Lawrence Gordon, Robert F. Colesberry Screenplay: David Aaron Cohen & Vincent Patrick and Kevin Jarre=20 based on a story by Kevin Jarre Cinematography: Gordon Willis Music: James Horner U.S. Distributor: Columbia Pictures
The advance word on THE DEVIL'S OWN was, to put it mildly, not=20 good. About a month ago, Brad Pitt went public with some extremely=20 damaging statements about how, if he hadn't possessed an iron-clad=20 contract, he would have bailed out on the production long before its=20 finish. Then there's the fact that Columbia Pictures delayed the=20 opening from late last year (during pre-Oscar nomination prime time) to=20 the dreary wasteland of March, supposedly as a result of awful preview=20 screenings. With these bits of knowledge spinning in my head, I was=20 ready for a disaster. But, while THE DEVIL'S OWN isn't going to win any=20 "best of=85" contests, it's not nearly as bad as I had been led to=20 believe.
Oh, there are problems, and some of them are fairly serious. But=20 the movie as a whole isn't a complete and utter waste of time. I didn't=20 leave the theater wringing my hands about having lost an evening. Part=20 of the reason THE DEVIL'S OWN is endurable is because, in spite of=20 various script deficiencies, both of the stars -- Pitt and Harrison Ford=20 -- have an undeniable screen presence. And, while star power can't save=20 a sinking movie, it can at least keep it afloat longer.
THE DEVIL'S OWN begins in a rousing enough fashion, with a short=20 prologue set in 1972, then a flash-forward twenty years to a police=20 action in Belfast. Frankie Maguire (Brad Pitt), a member of the=20 provisional IRA with more than 18 murders to his credit, is a wanted=20 man. When the British army, aided by the local police, corner him in a=20 warehouse, he and his compatriots fight back, and the result is a=20 bloodbath. Frankie escapes to the U.S. with the assignment to buy=20 stinger missiles from an arms dealer (Treat Williams) and bring them=20 back by boat to Ireland. =20
Frankie's "host" in the United States is IRA sympathizer Peter=20 Fitzsimmons (George Hearn), who sets him up with a bed and bathroom in=20 the suburban house of NYPD officer Tom O'Meara (Harrison Ford). Tom is=20 a prototypical "good cop" -- he doesn't lie, cheat, steal, or take=20 bribes, and puts the love of his wife (Margaret Colin) and children=20 above all else. He and Frankie, who's now going by the alias of Rory=20 Devaney, become friends. Of course, Tom doesn't know about Frankie's=20 terrorist background. In fact, he doesn't suspect that there's anything=20 sinister about his guest until a group of armed, masked men break into=20 his house and threaten to kill his wife.
For much of its running length, THE DEVIL'S OWN works as a passable=20 thriller. Certain plot elements (including many of the details=20 surrounding the missile deal) border on preposterous, but that often=20 goes with the territory in films of this genre. The best parts of THE=20 DEVIL'S OWN are the quiet moments, such as when Frankie and Tom are=20 talking, or when Tom is spending time with his family. There's also an=20 effective subplot that forces Tom to examine his moral outlook on life=20 when his partner (Ruben Blades) accidentally shoots a fleeing suspect in=20 the back. =20
Unfortunately, THE DEVIL'S OWN goes downhill fast in the final half=20 hour. Suddenly, it's as if every significant character in the film has=20 undergone a frontal lobotomy.  The final scenes are solid, but the stuff that=20 leads up to them is a problem.
As is always the case in a film featuring the IRA, murky Irish=20 politics are addressed, although veteran director Alan J. Pakula (ALL=20 THE PRESIDENT'S MEN, PRESUMED INNOCENT) does his utmost to make THE=20 DEVIL'S OWN approach these thorny issues in a non-judgmental, evenhanded=20 fashion by depicting good and evil on both sides. The most interesting=20 facet of the political side of the script is how Irish views are easily=20 distorted in America, an ocean away from the strife and violence. It's=20 easy to classify oneself as a "patriot" when all that's on the line are=20 a few dollars.
Pitt and Ford do credible jobs as Frankie and Tom. Despite his=20 character's brutal, bloody past, Pitt manages to capture our sympathy,=20 in large part because, aside from the killings, Frankie seems like a=20 likable sort of guy. Ford, in a role that's a far cry from the cocky=20 Han Solo, recalls Jack Ryan, the protagonist of PATRIOT GAMES and CLEAR=20 AND PRESENT DANGER -- a hero whose armor is just a little too shiny. =20 Supporting players include Margaret Colin (INDEPENDENCE DAY) as Tom's=20 wife, Natascha McElhone (SURVIVING PICASSO) as Frankie's girlfriend, and=20 a nasty Treat Williams as a gunrunner in a suit. =20
While THE DEVIL'S OWN doesn't do a spectacular job of fulfilling=20 the promise of its cast or its complex politics-and-guns premise, it is=20 nevertheless reasonably well-paced. The less intently you watch this=20 movie, the greater the chance that you'll be pleased by it. =20 Unfortunately, if you're paying attention, it won't take long to notice=20 that very little of the last act holds together. That sort of high- tension, mind-numbing climax makes it difficult for me to retain more=20 than token enthusiasm for the production as a whole.
- James Berardinelli e-mail<EMAIL_ADDRESS>ReelViews web site: http://www.cybernex.net/~berardin
The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).
The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.
Please direct comments/criticisms of the review to relevant newsgroups.
Broken URLs inthe reviews are the responsibility of the author.
The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.
Related links: index of all rec.arts.movies.reviews reviews


 Usually, they are placed in the area above the key signature & clef.
The tempo indicates the rate of speed at which a piece of music should be played. It is common practice to write tempo markings in Italian. On Musimatica, we have included a number of Italian tempo markings along with their English translations.
Click on the toolbar in the area marked Moderato. A menu displaying several tempo options should appear. Take a few moments to become familiar with the choices.
In order to change the tempo of your music, simply click on one of the items in the menu. This can be done at any time before, during, or after composing.
Instructions:
1. Set the clef and time signature to any values you'd like.
2. Begin placing notes on the staff. Try to incorporate several different note types into your piece.
3. When you have filled a few measures with notes, click on the tempo markings & choose an option from the menu. Click 'Generate Audio' & listen to the music. Be sure to count along with the beats & take note of the speed of the piece.
4. Choose another option from the tempo menu, and click 'Generate Audio' once more. Listen to how the pace of the music has changed. Choose a few more options to become familiar with the different tempo markings.
When you are comfortable navigating the tempo menu & are ready to move on, click 'Submit' to check your work.
{% endblock text %}


{% extends "base.html" %} {% block title %}{{ society_info.name }}{% endblock %} {% block content %}
Contact: {{ society_info.email }}
{% if session["auth"] == "ADMIN" %}Contact Advisor: {{ society_info["advisor-mail"] }}
{% endif %}{{ society_info.description }}
{% if userFlag == 1 %} {% elif userFlag == 2 %} {% endif %}| Event Name | Payed to | Cost |
|---|---|---|
| {{ cost.event }} | {{ cost.bill_detail }} | {{ cost.cost }} |
| Member Email |
|---|
| {{ member }} |
| Event Name | Name | Student No | |
|---|---|---|---|
| {{ attendee.e_name }} | {{ attendee.name }} | {{ attendee.no }} | {{ attendee.email }} |


This document describes the major changes in Ganeti 2.3 compared to the 2.2 version.
Contents
As for 2.1 and 2.2 we divide the 2.3 design into three areas:
Currently all nodes of a Ganeti cluster are considered as part of the same pool, for allocation purposes: DRBD instances for example can be allocated on any two nodes.
This does cause a problem in cases where nodes are not all equally connected to each other. For example if a cluster is created over two set of machines, each connected to its own switch, the internal bandwidth between machines connected to the same switch might be bigger than the bandwidth for inter-switch connections.
Moreover, some operations inside a cluster require all nodes to be locked together for inter-node consistency, and won’t scale if we increase the number of nodes to a few hundreds.
With this change we’ll divide Ganeti nodes into groups. Nothing will change for clusters with only one node group. Bigger clusters will be able to have more than one group, and each node will belong to exactly one.
To manage node groups and the nodes belonging to them, the following new commands and flags will be introduced:
gnt-group add <group> # add a new node group
gnt-group remove <group> # delete an empty node group
gnt-group list # list node groups
gnt-group rename <oldname> <newname> # rename a node group
gnt-node {list,info} -g <group> # list only nodes belonging to a node group
gnt-node modify -g <group> # assign a node to a node group
In clusters with more than one node group, it may be desirable to establish local policies regarding which groups should be preferred when performing allocation of new instances, or inter-group instance migrations.
To help with this, we will provide an alloc_policy attribute for node groups. Such attribute will be honored by iallocator plugins when making automatic decisions regarding instance placement.
The alloc_policy attribute can have the following values:
One operation at the node group level will be initially provided:
gnt-group drain <group>
The purpose of this operation is to migrate all instances in a given node group to other groups in the cluster, e.g. to reclaim capacity if there are enough free resources in other node groups that share a storage pool with the evacuated group.
With the introduction of node groups, instances will be required to live in only one group at a time; this is mostly important for DRBD instances, which will not be allowed to have their primary and secondary nodes in different node groups. To support this, we envision the following changes:
- The iallocator interface will be augmented, and node groups exposed, so that plugins will be able to make a decision regarding the group in which to place a new instance. By default, all node groups will be considered, but it will be possible to include a list of groups in the creation job, in which case the plugin will limit itself to considering those; in both cases, the alloc_policy attribute will be honored.
- If, on the other hand, a primary and secondary nodes are specified for a new instance, they will be required to be on the same node group.
- Moving an instance between groups can only happen via an explicit operation, which for example in the case of DRBD will work by performing internally a replace-disks, a migration, and a second replace-disks. It will be possible to clean up an interrupted group-move operation.
- Cluster verify will signal an error if an instance has nodes belonging to different groups. Additionally, changing the group of a given node will be initially only allowed if the node is empty, as a straightforward mechanism to avoid creating such situation.
- Inter-group instance migration will have the same operation modes as new instance allocation, defined above: letting an iallocator plugin decide the target group, possibly restricting the set of node groups to consider, or specifying a target primary and secondary nodes. In both cases, the target group or nodes must be able to accept the instance network- and storage-wise; the operation will fail otherwise, though in the future we may be able to allow some parameter to be changed together with the move (in the meantime, an import/export will be required in this scenario).
We expect the following changes for cluster management:
- Frequent multinode operations, such as os-diagnose or cluster-verify, will act on one group at a time, which will have to be specified in all cases, except for clusters with just one group. Command line tools will also have a way to easily target all groups, by generating one job per group.
- Groups will have a human-readable name, but will internally always be referenced by a UUID, which will be immutable; for example, nodes will contain the UUID of the group they belong to. This is done to simplify referencing while keeping it easy to handle renames and movements. If we see that this works well, we’ll transition other config objects (instances, nodes) to the same model.
- The addition of a new per-group lock will be evaluated, if we can transition some operations now requiring the BGL to it.
- Master candidate status will be allowed to be spread among groups. For the first version we won’t add any restriction over how this is done, although in the future we may have a minimum number of master candidates which Ganeti will try to keep in each group, for example.
Commands like gnt-cluster command/gnt-cluster copyfile will continue to work on the whole cluster, but it will be possible to target one group only by specifying it.
Commands which allow selection of sets of resources (for example gnt-instance start/gnt-instance stop) will be able to select them by node group as well.
Initially node groups won’t be taggable objects, to simplify the first implementation, but we expect this to be easy to add in a future version should we see it’s useful.
We envision groups as a good place to enhance cluster scalability. In the future we may want to use them as units for configuration diffusion, to allow a better master scalability. For example it could be possible to change some all-nodes RPCs to contact each group once, from the master, and make one node in the group perform internal diffusion. We won’t implement this in the first version, but we’ll evaluate it for the future, if we see scalability problems on big multi-group clusters.
When Ganeti will support more storage models (e.g. SANs, Sheepdog, Ceph) we expect groups to be the basis for this, allowing for example a different Sheepdog/Ceph cluster, or a different SAN to be connected to each group. In some cases this will mean that inter-group move operation will be necessarily performed with instance downtime, unless the hypervisor has block-migrate functionality, and we implement support for it (this would be theoretically possible, today, with KVM, for example).
Assuming the node groups feature will enable bigger clusters, other parts of Ganeti will be impacted even more by the (in effect) bigger clusters.
While many areas will be impacted, one is the most important: the fact that the watcher still needs to be able to repair instance data on the current 5 minutes time-frame (a shorter time-frame would be even better). This means that the watcher itself needs to have parallelism when dealing with node groups.
Also, the iallocator plugins are being fed data from Ganeti but also need access to the full cluster state, and in general we still rely on being able to compute the full cluster state somewhat “cheaply” and on-demand. This conflicts with the goal of disconnecting the different node groups, and to keep the same parallelism while growing the cluster size.
Another issue is that the current capacity calculations are done completely outside Ganeti (and they need access to the entire cluster state), and this prevents keeping the capacity numbers in sync with the cluster state. While this is still acceptable for smaller clusters where a small number of allocations/removal are presumed to occur between two periodic capacity calculations, on bigger clusters where we aim to parallelize heavily between node groups this is no longer true.
As proposed changes, the main change is introducing a cluster state cache (not serialised to disk), and to update many of the LUs and cluster operations to account for it. Furthermore, the capacity calculations will be integrated via a new OpCode/LU, so that we have faster feedback (instead of periodic computation).
A new cluster state cache will be introduced. The cache relies on two main ideas:
Given the above, it makes sense to cache the results of node and instance state (with a focus on the node state) inside the master daemon.
The cache will not be serialised to disk, and will be for the most part transparent to the outside of the master daemon.
The cache will be oriented with a focus on node groups, so that it will be easy to invalidate an entire node group, or a subset of nodes, or the entire cache. The instances will be stored in the node group of their primary node.
Furthermore, since the node and instance properties determine the capacity statistics in a deterministic way, the cache will also hold, at each node group level, the total capacity as determined by the new capacity iallocator mode.
The cache will be updated whenever a query for a node state returns “full” node information (so as to keep the cache state for a given node consistent). Partial results will not update the cache (see next paragraph).
Since there will be no way to feed the cache from outside, and we would like to have a consistent cache view when driven by the watcher, we’ll introduce a new OpCode/LU for the watcher to run, instead of the current separate opcodes (see below in the watcher section).
Updates to a node that change a node’s specs “downward” (e.g. less memory) will invalidate the capacity data. Updates that increase the node will not invalidate the capacity, as we’re more interested in “at least available” correctness, not “at most available”.
If a partial node query is done (e.g. just for the node free space), and the returned values don’t match with the cache, then the entire node state will be invalidated.
By default, all LUs will invalidate the caches for all nodes and instances they lock. If an LU uses the BGL, then it will invalidate the entire cache. In time, it is expected that LUs will be modified to not invalidate, if they are not expected to change the node’s and/or instance’s state (e.g. LUInstanceConsole, or LUInstanceActivateDisks).
Invalidation of a node’s properties will also invalidate the capacity data associated with that node.
The cache elements will have an upper bound on their lifetime; the proposal is to make this an hour, which should be a high enough value to cover the watcher being blocked by a medium-term job (e.g. 20-30 minutes).
The cache will be used by default for most queries (e.g. a Luxi call, without locks, for the entire cluster). Since this will be a change from the current behaviour, we’ll need to allow non-cached responses, e.g. via a --cache=off or similar argument (which will force the query).
The cache will also be used for the iallocator runs, so that computing allocation solution can proceed independent from other jobs which lock parts of the cluster. This is important as we need to separate allocation on one group from exclusive blocking jobs on other node groups.
The capacity calculations will also use the cache. This is detailed in the respective sections.
As detailed in the cluster cache section, the watcher also needs improvements in order to scale with the the cluster size.
As a first improvement, the proposal is to introduce a new OpCode/LU pair that runs with locks held over the entire query sequence (the current watcher runs a job with two opcodes, which grab and release the locks individually). The new opcode will be called OpUpdateNodeGroupCache and will do the following:
The reason for the per-node group query is that we don’t want a busy node group to prevent instance maintenance in other node groups. Therefore, the watcher will introduce parallelism across node groups, and it will possible to have overlapping watcher runs. The new execution sequence will be:
Each forked children will do the following:
This new mode of execution means that the master watcher processes might overlap in running, but not the individual per-node group child processes.
This change allows us to keep (almost) the same parallelism when using a bigger cluster with node groups versus two separate clusters.
Currently the watcher only does “small” queries for the node and instance state, and at first sight changing it to use the new OpCode which populates the cache with the entire state might introduce additional costs, which must be payed every five minutes.
However, the OpCodes that the watcher submits are using the so-called dynamic fields (need to contact the remote nodes), and the LUs are not selective—they always grab all the node and instance state. So in the end, we have the same cost, it just becomes explicit rather than implicit.
This ‘grab all node state’ behaviour is what makes the cache worth implementing.
The design above only deals with inter-node group issues. It still makes sense to run instance maintenance for nodes A and B if only node C is locked (all being in the same node group).
This problem is commonly encountered in previous Ganeti versions, and it should be handled similarly, by tweaking lock lifetime in long-duration jobs.
TODO: add more ideas here.
The splitting of node group maintenance to different children which will run in parallel requires that the state file handling changes from monolithic updates to partial ones.
There are two file that the watcher maintains:
For the first file, since it’s used only internally to the watchers, we can move to a per node group configuration.
For the second file, even if it’s used as an external interface, we will need to make some changes to it: because the different node groups can return results at different times, we need to either split the file into per-group files or keep the single file and add a per-instance timestamp (currently the file holds only the instance name and state).
The proposal is that each child process maintains its own node group file, and the master process will, right after querying the node group list, delete any extra per-node group state file. This leaves the consumers to run a simple cat instance-status.group-* to obtain the entire list of instance and their states. If needed, the modify timestamp of each file can be used to determine the age of the results.
Currently, the capacity calculations are done completely outside Ganeti. As explained in the current problems section, this needs to account better for the cluster state changes.
Therefore a new OpCode will be introduced, OpComputeCapacity, that will either return the current capacity numbers (if available), or trigger a new capacity calculation, via the iallocator framework, which will get a new method called capacity.
This method will feed the cluster state (for the complete set of node group, or alternative just a subset) to the iallocator plugin (either the specified one, or the default if none is specified), and return the new capacity in the format currently exported by the htools suite and known as the “tiered specs” (see hspace(1)).
Currently, the “tspec” calculations done in hspace require some additional parameters:
For the integration in Ganeti, there are multiple ways to pass these:
Since the first option is not consistent with the intended changes, a combination of the last two is proposed:
Whenever the capacity is requested via different parameters, it will invalidate the cache, even if otherwise the cache is up-to-date.
The new parameters are:
These might also be used in instance creations (to be determined later, after they are introduced).
Input:
Output:
Note that due to the way the tspecs are computed, for any given specification, the total available count is the count for the given entry, plus the sum of counts for higher specifications.
Currently all nodes are, from the point of view of their capabilities, homogeneous. This means the cluster considers all nodes capable of becoming master candidates, and of hosting instances.
This prevents some deployment scenarios: e.g. having a Ganeti instance (in another cluster) be just a master candidate, in case all other master candidates go down (but not, of course, host instances), or having a node in a remote location just host instances but not become master, etc.
Two new capability flags will be added to the node:
In terms of the other flags, master_capable is a stronger version of “not master candidate”, and vm_capable is a stronger version of “drained”.
For the master_capable flag, it will affect auto-promotion code and node modifications.
The vm_capable flag will affect the iallocator protocol, capacity calculations, node checks in cluster verify, and will interact in novel ways with locking (unfortunately).
It is envisaged that most nodes will be both vm_capable and master_capable, and just a few will have one of these flags removed. Ganeti itself will allow clearing of both flags, even though this doesn’t make much sense currently.
Currently all jobs and opcodes have the same priority. Once a job started executing, its thread won’t be released until all opcodes got their locks and did their work. When a job is finished, the next job is selected strictly by its incoming order. This does not mean jobs are run in their incoming order—locks and other delays can cause them to be stalled for some time.
In some situations, e.g. an emergency shutdown, one may want to run a job as soon as possible. This is not possible currently if there are pending jobs in the queue.
Each opcode will be assigned a priority on submission. Opcode priorities are integers and the lower the number, the higher the opcode’s priority is. Within the same priority, jobs and opcodes are initially processed in their incoming order.
Submitted opcodes can have one of the priorities listed below. Other priorities are reserved for internal use. The absolute range is -20..+19. Opcodes submitted without a priority (e.g. by older clients) are assigned the default priority.
- High (-10)
- Normal (0, default)
- Low (+10)
As a change from the current model where executing a job blocks one thread for the whole duration, the new job processor must return the job to the queue after each opcode and also if it can’t get all locks in a reasonable timeframe. This will allow opcodes of higher priority submitted in the meantime to be processed or opcodes of the same priority to try to get their locks. When added to the job queue’s workerpool, the priority is determined by the first unprocessed opcode in the job.
If an opcode is deferred, the job will go back to the “queued” status, even though it’s just waiting to try to acquire its locks again later.
If an opcode can not be processed after a certain number of retries or a certain amount of time, it should increase its priority. This will avoid starvation.
A job’s priority can never go below -20. If a job hits priority -20, it must acquire its locks in blocking mode.
Opcode priorities are synchronised to disk in order to be restored after a restart or crash of the master daemon.
Priorities also need to be considered inside the locking library to ensure opcodes with higher priorities get locks first. See locking priorities for more details.
To support job priorities in the job queue, the worker pool underlying the job queue must be enhanced to support task priorities. Currently tasks are processed in the order they are added to the queue (but, due to their nature, they don’t necessarily finish in that order). All tasks are equal. To support tasks with higher or lower priority, a few changes have to be made to the queue inside a worker pool.
Each task is assigned a priority when added to the queue. This priority can not be changed until the task is executed (this is fine as in all current use-cases, tasks are added to a pool and then forgotten about until they’re done).
A task’s priority can be compared to Unix’ process priorities. The lower the priority number, the closer to the queue’s front it is. A task with priority 0 is going to be run before one with priority 10. Tasks with the same priority are executed in the order in which they were added.
While a task is running it can query its own priority. If it’s not ready yet for finishing, it can raise an exception to defer itself, optionally changing its own priority. This is useful for the following cases:
With these changes, the job queue will be able to implement per-job priorities.
In order to support priorities in Ganeti’s own lock classes, locking.SharedLock and locking.LockSet, the internal structure of the former class needs to be changed. The last major change in this area was done for Ganeti 2.1 and can be found in the respective design document.
The plain list ([]) used as a queue is replaced by a heap queue, similar to the worker pool. The heap or priority queue does automatic sorting, thereby automatically taking care of priorities. For each priority there’s a plain list with pending acquires, like the single queue of pending acquires before this change.
When the lock is released, the code locates the list of pending acquires for the highest priority waiting. The first condition (index 0) is notified. Once all waiting threads received the notification, the condition is removed from the list. If the list of conditions is empty it’s removed from the heap queue.
Like before, shared acquires are grouped and skip ahead of exclusive acquires if there’s already an existing shared acquire for a priority. To accomplish this, a separate dictionary of shared acquires per priority is maintained.
To simplify the code and reduce memory consumption, the concept of the “active” and “inactive” condition for shared acquires is abolished. The lock can’t predict what priorities the next acquires will use and even keeping a cache can become computationally expensive for arguable benefit (the underlying POSIX pipe, see pipe(2), needs to be re-created for each notification anyway).
The following diagram shows a possible state of the internal queue from a high-level view. Conditions are shown as (waiting) threads. Assuming no modifications are made to the queue (e.g. more acquires or timeouts), the lock would be acquired by the threads in this order (concurrent acquires in parentheses): threadE1, threadE2, (threadS1, threadS2, threadS3), (threadS4, threadS5), threadE3, threadS6, threadE4, threadE5.
[
(0, [exc/threadE1, exc/threadE2, shr/threadS1/threadS2/threadS3]),
(2, [shr/threadS4/threadS5]),
(10, [exc/threadE3]),
(33, [shr/threadS6, exc/threadE4, exc/threadE5]),
]
Currently Ganeti does not support IPv6. This is true for nodes as well as instances. Due to the fact that IPv4 exhaustion is threateningly near the need of using IPv6 is increasing, especially given that bigger and bigger clusters are supported.
In Ganeti 2.3 we introduce additionally to the ordinary pure IPv4 setup a hybrid IPv6/IPv4 mode. The latter works as follows:
The reason for this hybrid setup is that key components that Ganeti depends on do not or only partially support IPv6. More precisely, Xen does not support instance migration via IPv6 in version 3.4 and 4.0. Similarly, KVM does not support instance migration nor VNC access for IPv6 at the time of this writing.
This led to the decision of not supporting pure IPv6 Ganeti clusters, as very important cluster operations would not have been possible. Using IPv4 as secondary address does not affect any of the goals of the IPv6 support: since secondary addresses do not need to be publicly accessible, they need not be globally unique. In other words, one can practically use private IPv4 secondary addresses just for intra-cluster communication without propagating them across layer 3 boundaries.
Currently common utility functions are kept in the utils module. Since this module grows bigger and bigger network-related functions are moved to a separate module named netutils. Additionally all these utilities will be IPv6-enabled.
As mentioned above there will be two different setups in terms of IP addressing: pure IPv4 and hybrid IPv6/IPv4 address. To choose that a new cluster init parameter –primary-ip-version is introduced. This is needed as a given name can resolve to both an IPv4 and IPv6 address on a dual-stack host effectively making it impossible to infer that bit.
Once a cluster is initialized and the primary IP version chosen all nodes that join have to conform to that setup. In the case of our IPv6/IPv4 setup all nodes must have a secondary IPv4 address.
Furthermore we store the primary IP version in ssconf which is consulted every time a daemon starts to determine the default bind address (either <IP_ADDRESS> or ::. In a IPv6/IPv4 setup we need to bind the Ganeti daemon listening on network sockets to the IPv6 address.
When adding a new node to a IPv6/IPv4 cluster it must have a IPv6 address to be used as primary and a IPv4 address used as secondary. As explained above, every time a daemon is started we use the cluster primary IP version to determine to which any address to bind to. The only exception to this is when a node is added to the cluster. In this case there is no ssconf available when noded is started and therefore the correct address needs to be passed to it.
Since the gethostbyname*() functions do not support IPv6 name resolution will be done by using the recommended getaddrinfo().
| Component | IPv6 Status | Planned Version |
|---|---|---|
| Xen instance migration | Not supported | Xen 4.1: libxenlight |
| KVM instance migration | Not supported | Unknown |
| KVM VNC access | Not supported | Unknown |
In Ganeti 2.2 we introduced privilege separation for the RAPI daemon. This was done directly in the daemon’s code in the process of daemonizing itself. Doing so leads to several potential issues. For example, a file could be opened while the code is still running as root and for some reason not be closed again. Even after changing the user ID, the file descriptor can be written to.
To address these shortcomings, daemons will be started under the target user right away. The start-stop-daemon utility used to start daemons supports the --chuid option to change user and group ID before starting the executable.
The intermediate solution for the RAPI daemon from Ganeti 2.2 will be removed again.
Files written by the daemons may need to have an explicit owner and group set (easily done through utils.WriteFile).
All SSH-related code is removed from the ganeti.bootstrap module and core components and moved to a separate script. The core code will simply assume a working SSH setup to be in place.
In order to separate the permissions of file sets we separate them into the following 3 overall security domain chunks:
So for point 3 this tables shows the correlation of the sets to groups and their users:
| Set | Group | Users | Description |
|---|---|---|---|
| A | gntrapi | gntrapi, gntmasterd | Share data between gntrapi and gntmasterd |
| B | gntadmins | gntrapi, gntmasterd, users | Shared between users who needs to call gntmasterd |
| C | gntconfd | gntconfd, gntmasterd | Share data between gntconfd and gntmasterd |
| D | gntmasterd | gntmasterd | masterd only; Currently only to redistribute the configuration, has access to all files under lib/ganeti |
| E | gntdaemons | gntmasterd, gntrapi, gntconfd | Shared between the various Ganeti daemons to exchange data |
The following commands still require root permissions to fulfill their functions:
gnt-cluster {init|destroy|command|copyfile|rename|masterfailover|renew-crypto}
gnt-node {add|remove}
gnt-instance {console}
Here’s how we propose to change the filesystem hierarchy and their permissions.
Assuming it follows the defaults: gnt${daemon} for user and the groups from the section Security Domains:
${localstatedir}/lib/ganeti/ (0755; gntmasterd:gntmasterd)
cluster-domain-secret (0600; gntmasterd:gntmasterd)
config.data (0640; gntmasterd:gntconfd)
hmac.key (0440; gntmasterd:gntconfd)
known_host (0644; gntmasterd:gntmasterd)
queue/ (0700; gntmasterd:gntmasterd)
archive/ (0700; gntmasterd:gntmasterd)
* (0600; gntmasterd:gntmasterd)
* (0600; gntmasterd:gntmasterd)
rapi.pem (0440; gntrapi:gntrapi)
rapi_users (0640; gntrapi:gntrapi)
server.pem (0440; gntmasterd:gntmasterd)
ssconf_* (0444; root:gntmasterd)
uidpool/ (0750; root:gntmasterd)
watcher.data (0600; root:gntmasterd)
${localstatedir}/run/ganeti/ (0770; gntmasterd:gntdaemons)
socket/ (0750; gntmasterd:gntadmins)
ganeti-master (0770; gntmasterd:gntadmins)
${localstatedir}/log/ganeti/ (0770; gntmasterd:gntdaemons)
master-daemon.log (0600; gntmasterd:gntdaemons)
rapi-daemon.log (0600; gntrapi:gntdaemons)
conf-daemon.log (0600; gntconfd:gntdaemons)
node-daemon.log (0600; gntnoded:gntdaemons)


Excuse the mess
Over the last month I've been working implementing the philosophy of BEM ( Block, Element, Modifier ) with my CSS. I have to admit it's been tough. I feel the frustrations are coming from keeping all my class and files orgainized. I do tend to fall back to old ways which makes things even more difficult. Also I'm not saying my old ways are bad but they weren't great.
As of now I'm only following this method on my current project which is a bit messy. I will be going back to clean things up when I'm done but for now excuse my mess.
In all I'm enjoying writing my CSS in this fasion with hopes of making a "boilerplate/styleguide" going forward.
- Previous: A Follow-up to My Pledge
- Next: Monday


EMBARC
Journey Memories
Create Memory
Feedback
Reflection
Log-in
FEEDBACK
Why did you give this journey this rating?
What did you like best about this journey?
What would you add to this journey or how would you improve it?


Principal Investigator: Prof. Phillipa Gill
To document and analyze the practice of national-level Internet censorship through the creation of a global network of researchers running censorship measurement software. This measurement software will run tests from your computer or dedicated hardware device which attempt to access a list of sensitive URLs. The software will collect data from these tests and send it back to servers hosted at the University of Toronto which are maintained by the researchers. Data will be analyzed at Stony Brook University. These data will be used to determine what content is being censored, what technical methods are used for censorship and how censorship changes over time.
It is anticipated that there will be 15 subjects in the study overall. It is not anticipated that any will enroll at Stony Brook University. You are eligible to participate in this research if you have a computer that meets the software’s minimum requirements and you have signed this consent form.
The potential risks posed by conducting these tests are highly specific to the context in which the tests take place. These risks are highly dependent on the domestic political and legal context in your country.
The data that the tool will collect are regularly transmitted on the Internet and the measurement tests do not compromise, circumvent or otherwise disrupt the regular functioning of the networks being probed. While we know of no explicit laws that forbid the collection of network measurements on Internet censorship, the nature of this research can potentially have political impacts and could be seen unfavorably by certain authorities. If an authority is sensitive to information of its censorship regime being exposed and views exposure as potentially damaging then nationals of that country who are found to be engaged in this study may be scrutinized by the authorities.
While it is challenging to definitively identify what the risks of conducting these tests may be in your country, we have compiled a number of metrics to help inform you of the potential risks in your country.


Our luxury honey set perfect for a gift. Includes our organic raw honey, a jar of bee pollen and a serving spoon plus a bag of organic fair trade pistachios.
Locally produced by one of our local artisans our bee decorated tea cups will brighten your kitchen. Buy one or a as many as you need in our shop
A shopping bag made using responsible printing materials and organic cotton. Save on carrier bags and carry your favourite insect
A choice of our finest homemade honey; all organic and made in house by us. Enjoy all the health benefits from locally sourced honey
An organic cotton throw printed using responsible materials in our own village. Keep those heating bills down this winter
Our stylist honey pot produced locally using eco friendly materials and techniques. And a honey spoon to help you serve our sweet honey
Our honey is full of nutrients and antioxidants and it is of the
finest quality. A much healthier option than sugar for your tea or
coffee.
Honey can help you lower your cholesterol levels and triglycerides
and it also can reduce blood pressure and inflammation.
With its goodness the antioxidants will benefit your heart’s general
health.


EUR/USD: Bulls regain poise, 1.1100 back on sight?
by Dhwani Mehta- EUR/USD bounces-off lows ahead of 5-DMA support at 1.1055.
- Bulls back in charge as broad USD recovery stalls amid trade woes, Trump’s tweet.
- Focus stays on Eurozone/ US data and trade developments ahead of FOMC minutes.
Having found fresh buyers ahead of the 5-DMA support of 1.1055 in early Asia, the EUR/USD pair is seen heading back towards the weekly tops of 1.1090 amid a pause in broad-based US dollar recovery.
China walking back trade deal
The bulls are back in charge, as we progress towards the European opening bells after the US President Trump’s tweet on relatively higher Fed rates stalled the tepid recovery in the US dollar across its main competitors. The USD index is off the session highs at 97.86 to now trade flat at 97.79. Trump said that he told Powell the Fed Rate is set too high relative to the interest rates of other competitor countries.
The US dollar was downed to two-week lows of 97.68 on Monday after fresh US-China trade deal doubts resurfaced and dampened the investors’ mood. “Trade deal concerns translated into lower US yields, falling stocks, a weaker greenback, and higher demand for safe-havens in financial markets,” FXStreet’s Chief Analyst Valeria Bednarik noted.
According to a CNBC report published overnight, the mood in Beijing was pessimistic about the prospects of sealing the Phase One agreement with the US after Trump said no tariff rollback and as China awaits the outcome on US President’s impeachment row.
Looking ahead, the US-China trade-driven sentiment will remain the main market motor, in light of second-tier macro releases on both sides of the Atlantic. “October’s US housing starts will be released on Tuesday, while investors should be closely following the release of the Federal Reserve's latest meeting minutes on Wednesday and the European Central Bank minutes on Thursday. ECB President Christine Lagarde is due to speak in Frankfurt later in the week,” Valeria added.
EUR/USD Technical levels to consider
EUR/USD
| Overview | |
|---|---|
| Today last price | 1.1075 |
| Today Daily Change | 0.0000 |
| Today Daily Change % | 0.00 |
| Today daily open | 1.1074 |
| Trends | |
|---|---|
| Daily SMA20 | 1.1083 |
| Daily SMA50 | 1.1043 |
| Daily SMA100 | 1.1095 |
| Daily SMA200 | 1.1179 |
| Levels | |
|---|---|
| Previous Daily High | 1.1092 |
| Previous Daily Low | 1.1048 |
| Previous Weekly High | 1.1058 |
| Previous Weekly Low | 1.0989 |
| Previous Monthly High | 1.118 |
| Previous Monthly Low | 1.0879 |
| Daily Fibonacci 38.2% | 1.1075 |
| Daily Fibonacci 61.8% | 1.1065 |
| Daily Pivot Point S1 | 1.1051 |
| Daily Pivot Point S2 | 1.1028 |
| Daily Pivot Point S3 | 1.1008 |
| Daily Pivot Point R1 | 1.1095 |
| Daily Pivot Point R2 | 1.1115 |
| Daily Pivot Point R3 | 1.1138 |