In my seminal work, “Chaotic Creatia,” I described the means by which those creatures known to us as Daedra manifest themselves upon the mortal plane. It is this mechanism that makes it impossible to ever truly kill a Daedra, because they simply return to the planes of Oblivion and then project themselves back to the Mundus once again. The implication is that there are (and always will be) bonds between these planes and our own.
This begs the question, however, if you kill a Daedra within its respective plane of Oblivion, is it then truly annihilated? What about if the Daedra is slain while within one of the Aedric planes of existence? I am fortunate enough to have had the privilege of engaging several Daedra on this subject and I can assure you that they are not forthcoming on this topic.
What I have been able to glean, mostly by way of observing their reactions to my suggestions, is that Daedra do not often, nor do they appear to care to, travel to the planes of existence dominated by Aedric influences. Realms such as the many varieties of Aetherius (Sovngarde being a prime example) do not appear suitable for the travel of Daedric creatures.
I would hypothesize based on this information, and from information gathered from other sources, that the Aedric planes do not share the same energetic tie to the Daedric planes that they share to one another and to the Mundus. Thus, it might be possible that a Daedric vestige slain in an Aedric plane cannot return to its home plane, and thus is left dead or simply trapped for all eternity. The irony doesn’t escape me that if this proves true, then a Daedra can only truly die after it enters heaven.
(Ah, how I amuse myself. All pure speculation, of course — but the time does pass slowly here, when it’s passing at all. One must stay busy!)


Match Play. Red leads 4-3 to 5 (Crawford). How should Red play 32?
pips Red=92 White=105
(CorrectAnswer= 0/0, ErrorScore= 0)
This is close. At most scores 8/3* would be correct because of the gammons won.
With gammons of no value to Red the more cautious 8/6, 8/5 is correct. However, 8/3 is not technically an error.
With gammons of no value to Red the more cautious 8/6, 8/5 is correct. However, 8/3 is not technically an error.
1. Cubeful 2-ply 8/6 8/5 Eq.: +0.013 0.561 0.130 0.001 - 0.439 0.055 0.001 2. Cubeful 2-ply 8/3* Eq.: -0.070 (-0.083) 0.629 0.351 0.003 - 0.371 0.164 0.005 3. Cubeful 0-ply 6/4 6/3* Eq.: -0.367 (-0.380) 0.477 0.141 0.002 - 0.523 0.160 0.003 4. Cubeful 0-ply 8/5 4/2 Eq.: -0.379 (-0.392) 0.435 0.084 0.001 - 0.565 0.125 0.002 5. Cubeful 0-ply 8/6 4/1 Eq.: -0.385 (-0.398) 0.431 0.077 0.001 - 0.569 0.124 0.003


Swift callbacks
In some cases, we need to call C/C++ code from Swift and even Swift from C/C++. Code in Swift is only compatible with C, so you cannot
call C++ from it. You must use bridge and C-API to call C++ methods.
Calling C++ from Swift
This is very similar to calling C++ from DLL
1) We create C++ class in a file CppClass.h:
#ifndef CppClass_h
#define CppClass_h
class CppClass{
public:
CppClass() {}
void HelloWorld() { printf("Hello World"); }
}
#endif //CppClass_h
2) Now, to expose C API for external use CApi.h. We cannot use forward declaration with class for
return types, so we create “typedef struct” and named it “CCppClass” (C for C API prefix - better readibility).
#ifndef CApi_h
#define CApi_h
typedef struct CppClass CCppClass;
#ifdef __cplusplus
extern "C" {
#endif
CCppClass * CreateCppClass();
void ReleaseCppClass(CCppClass * c);
void CallHelloWorld(CCppClass * c);
#ifdef __cplusplus
}
#endif
#endif // CApi_h
3) In the next step, we create actuall API implementation in CApi.c:
#include "./CApi.h"
#include "./CppClass.h"
CCppClass * CreateCppClass(){
return new CppClass();
}
void ReleaseCppClass(CCppClass * c){
delete c;
}
void CallHelloWorld(CCppClass * c){
c->HelloWorld();
}
4) In Swift, we cannot directly include C code, we must create "a bridge". This is a simple file, that contains included files
and is auto-loaded by Swift compiler. However, we have to add this file to compiler settings.
How to create a Swift Bridging Header Manually
- Add a new file to Xcode (File > New > File), then select “Source” and click “Header File“.
- Name your file “XXX-Bridging-Header.h”.
- Create the file.
- Navigate to your project build settings and find the “Swift Compiler – Code Generation” section. You may find it faster to type in “Swift Compiler” into the search box to narrow down the results. Note: If you don’t have a “Swift Compiler – Code Generation” section, this means you probably don’t have any Swift classes added to your project yet. Add a Swift file, then try again.
- Next to “Objective-C Bridging Header” you will need to add the name/path of your header file. If your file resides in your project’s root folder simply put the name of the header file there. Examples: “ProjectName/ProjectName-Bridging-Header.h” or simply “ProjectName-Bridging-Header.h”.
- Open up your newly created bridging header and add includes for C++ or imports for Objective-C. Any class listed in this file will be able to be accessed from your swift classes.
5) Now, we can finally use our C++ class from Swift
var myCppClass:OpaquePointer? = nil;
myCppClass = CreateCppClass();
CallHelloWorld(myCppClass);
ReleaseCppClass(myCppClass);
Source:
- http://stackoverflow.com/questions/33260808/how-to-use-instance-method-as-callback-for-function-which-takes-only-func-or-lit/33262376#33262376
- http://stackoverflow.com/questions/1061005/calling-objective-c-method-from-c-method/1061576#1061576
- http://www.learnswiftonline.com/getting-started/adding-swift-bridging-header/
Calling Swift from C/C++
Calling Swift from C/C++ is a bit complicated. It can be divided into two parts - calling simple method or calling class member method.
The first type is quite easy, because Swift methods are directly mapable to C function pointers.
Both approaches are combined with the first part of this tutorial - C methods have to be made visible to Swift via bridge.
So I asume that is is already done, so I skip this in this samples.
C code:
void CallSwiftFromC(void(*f)()){
f();
}
Swift code:
func TestMethod(){
//Some Swift code
}
class SwiftClass{
func SomeFunc(){
CallSwiftFromC(TestMethod);
}
}
Now, the second type of callback is more complicated. We want to call Swift class member method from C/C++.
Is is not directly possible, so we have to pass pointer to Swift class along. We have created Callbacks struct, that holds
pointer to callback method and clas pointer. This is because we want to store callback in “std::function” and we dont
want to modify some underlying code. For example, “std::function” can be in some other class and we dont have source code
for it and without modifying the class, it wont be possible to call the Swift method. We have used lambda function to wrap
modified callback and each time the actuall “std::function” is called, our lambda is called first and loads data from Callbacks struct.
typedef struct Callbacks
{
void * classPtr;
void(*callback)(void *);
}Callbacks;static Callbacks * callbacks = new Callbacks();
void CallSwiftMemberFromC(void * classPtr, void(*callback)(void *))
{
callbacks->classPtr = classPtr;
callbacks->callback = callback;
std::function<void()> actaulCallback = [&](){
callbacks->callback(callbacks->classPtr);
};
actaulCallback();
}
In Swift, we have to obtain pointer to class. We use a helper function “bridge” to get it.
We can use closure passed to CallSwiftMemberFromC to "shorten" code a bit. The closure conforms to “void(*callback)(void *)”.
func bridge(_ obj : T) -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer(Unmanaged.passUnretained(obj).toOpaque())
}
func bridge(_ ptr : UnsafeMutableRawPointer) -> T? {
return Unmanaged.fromOpaque(ptr).takeUnretainedValue()
}
class SwiftClass{
func SomeFunc(){
CallSwiftMemberFromC(bridge(self), {(observer) -> Void in
// Extract pointer to `self` from void pointer:
let mySelf = Unmanaged.fromOpaque(observer!).takeUnretainedValue()
// Call instance method:
mySelf.TestMethod();
});
}
func TestMethod(){
}
}
Source:
- http://stackoverflow.com/questions/33294620/how-to-cast-self-to-unsafemutablepointervoid-type-in-swift
- http://stackoverflow.com/questions/33260808/how-to-use-instance-method-as-callback-for-function-which-takes-only-func-or-lit/33262376#33262376
Martin Prantl 2017


You are viewing an historical archive of past issues. Please report new issues to the appropriate project issue tracker on GitHub.
Comments
-
Greg Hurrell
Here's what I replied:
Thanks for the message. I hadn't heard about this one before.
My guess is that commit 70a8f9c9 is responsible. Specifically the "hasmapto()" function, which the Vim help describes as:
The result is a Number, which is 1 if there is a mapping that contains {what} in somewhere in the rhs (what it is mapped to) and this mapping exists in one of the modes indicated by {mode}.
So it sees a mapping for CommandTFlush, and so hasmapto() returns 1 and CommandT doesn't get its mapping any more. Will see if I can find a fix.
-
Greg Hurrell
Fixed in commit dfc4e191604. Will mark this one as closed.
-
Greg Hurrell
Status changed:
- From: new
- To: closed
Add a comment
Comments are now closed for this issue.


HomePage
Create new hero
Hero name :
Upload picture
Likes
Dislikes
Important
Liens sociaux
Team :
None
Avengers
X-men
Reset Form
Create new Hero


Before Change
return
elif self.is_fully_stopped():
LOGGER.debug("Spawning script thread...")
self._set_state(State.STARTING_THREAD)
script_thread = threading.Thread(
target=self._run,
name="Streamlit script runner thread")
After Change
If the script is not already running, it will be started immediately.
Otherwise, a rerun will be requested.
if self.is_shutdown():
LOGGER.warning("Discarding RERUN event after shutdown")
return
self._event_queue.enqueue(ScriptEvent.RERUN, self._report)
def request_stop(self):
if self.is_shutdown():


Enter the name of your project (15 chars max)
Enter the objective: (15 chars max)
How many people do you want to see every tile before you consider it finished?
(3 default) - more is recommended for harder tasks with harder to spot objects
Make sure you have permission. Google hasn't given permission yet and won't work until a proper API key is given.
Enter the name of your project (15 chars max)
You should get yours from pete masters if you don't have one.
Right click your KML file, copy the contents, and paste it in here
Make sure you have the rights to use this image. It should end with .jpg or .png
Please check with somebody from Mapswipe that your submission is correct.
Contact Pete Masters to receive a key to add projects. After you have the key, you can submit a project.


{% extends "base.html" %} {% set current_page_id = 'index' %} {% block title %}Lingofunk{% endblock %} {% block body %}
| # | Name | Description |
|---|---|---|
| 1 | Classify sentiment | Check whether the review is positive or negative |
| 2 | Compare reviews by relevance | Check how relevant a pair of reviews are to each other |
| 3 | Generate text of the given sentiment class | Generate text of the given sentiment: positive, negative or neutral |
| 4 | Generate text of the given sentiment degree | Generate text with given fraction of positive or negative sentiment |
| 5 | Regenerate text by tweaking its hidden representation | Change the direction and magnitude of the encoded text representation to generate new patterns |
| 6 | Transfer style | Generate a review of the same style, but different sentiment |
| 7 | Interpolate | Given two reviews, find the spectrum of their sentiment |


{{Expand Italian|Corzetti|date=August 2014}} {{Infobox prepared food | name = Corzetti | image = | caption = | alternate_name = | country = Italy | region = Liguria | creator = | course = | type = Pasta | served = | main_ingredient = | variations = | calories = | other = }}
Corzetti (in Genoese dialect curzetti) are a kind of fresh pasta typical of the Ligurian cuisine of north-west Italy, and traditional also in the area of Novi Ligure just across the border with Piedmont in the Province of Alessandria. They are similar to another Ligurian pasta called Croxetti.
There are two different kinds of corzetti. Those from the Val Polcevera, one of the principal valleys of the area of Genoa are made in "figure of eight" shape. Elsewhere curzetti stampae (“pressed” or “stamped” corzetti) are found. These are small, thin rounds of pasta that are given an embossed decoration using a special wooden hand-tool. The embossing is indeed more than decoration, as it helps the pasta to hold its sauce better. In the historic centre of Genoa are still traditional pasta shops where the corzetti are handmade and where they make these tools to make them with.
Besides the artisanal production, corzetti are also made on an industrial basis using ravioli machines made by such companies as Arienti & Cattaneo, Ima, Ostoni and Zamboni.
Contents |
A pasta dough is made using flour, water and salt<ref>Egg-based doughs may also be used, and white wine may be added.</ref> and rolled out into a sheet. The pasta is cut into rounds that are stamped to form the embossed relief, and left to dry for a while. After boiling in salted water they are typically dressed with a walnut or mushroom sauce (the latter called Tocco de funzi, in Genoese) or alternatively with pesto. Around Novi a sauce of mushrooms and sausages is common.
<gallery> File:Freshly stamped corzetti pasta disc.jpg|Freshly stamped corzetti pasta disc. File:Top view of Wooden Corzetti Stamp.jpg|Top view of Wooden Corzetti Stamp. File:Bottom view of Wooden Corzetti Stamp.jpg|Bottom view of Wooden Corzetti Stamp. </gallery>
{{Reflist}}
{{Pasta}}


Account balances
Server
Domains
Account information
Server
Backup
Snapshot
DNS
Account
Droplets
Snapshots
Domains
SSH Keys
Account
Profile
Invoices
Linode instances
Domains
Account
Invoices
Credits
Applications
dynos
Domains
Account
Domains
DNS records
Page rules
Account
Domains
DNS records
Email forwards
Account
Domains
Name servers
DNS records
Email forwards
Show/Hide tabs
API keys


Neuroplasticity is the ability of the brain to modify its connections or re-wire itself. Having an understanding of Neuroplasticity in a learning environment means that students understand that knowledge is not a set value, and that everybody has the capacity to learn. and that the more you the better you will become at it.
I could begin practising tasks, leading to strengthened neural pathways. As Neurologist Judy Willis says, "Practice makes permanent. The more times the network is stimulated, the stronger and more efficient it becomes."
Sleep and Meditation, regular exercise, reading fiction, learning an instrument, dancing have all been linked to increasing your neuroplasticity. Thinking about a certain topic as well as practising new skills have also been linked to increased neuroplasticity.
https://www.huffpost.com/entry/10-proven-ways-to-grow-yo_b_10374730
Psychologist Carol Dwek describes a fixed and growth mindset as “In a fixed mindset students believe their basic abilities, their intelligence, their talents, are just fixed traits.  In a growth mindset students understand that their talents and abilities can be developed through effort, good teaching and persistence. They don’t necessarily think everyone’s the same or anyone can be Einstein, but they believe everyone can get smarter if they work at it.” It’s relevant to learning in EDA as we are dealing with a large amount of new information and constantly tackling new and difficult challenges. If we are open to them and approach our learning with a ‘growth mindset’ then we will be much more likely to achieve.
I will remember to embrace challenges. When I don’t come to a desired outcome I will remember the Carol Dweck term ‘Not Yet’.
It was a good reminder to embrace challenges and persist in the face of setbacks.
The diagram on the Learning Hub page was helpful, I've saved it as a daily reminder.


*** User 2017-05-05 20:39:44.233 ***
20:39:44.233 [info] Disabling blocking sync...
*** User 2017-05-05 20:39:44.238 ***
20:39:44.238 [info] Configured peer_service_manager partisan_default_peer_service_manager on node 'node-1@MacBook-Pro-de-Anne-France'
*** User 2017-05-05 20:39:45.741 ***
20:39:45.740 [info] Enabling membership...
*** User 2017-05-05 20:39:45.742 ***
20:39:45.742 [info] Disabling blocking sync...
*** User 2017-05-05 20:39:45.747 ***
20:39:45.747 [info] Configured peer_service_manager partisan_default_peer_service_manager on node 'node-2@MacBook-Pro-de-Anne-France'
*** User 2017-05-05 20:39:47.209 ***
20:39:47.209 [info] Enabling membership...
*** User 2017-05-05 20:39:47.211 ***
20:39:47.211 [info] Disabling blocking sync...
*** User 2017-05-05 20:39:47.216 ***
20:39:47.216 [info] Configured peer_service_manager partisan_default_peer_service_manager on node 'node-3@MacBook-Pro-de-Anne-France'
*** User 2017-05-05 20:39:47.459 ***
Joining node: 'node-3@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 60181
*** User 2017-05-05 20:39:47.460 ***
Joining issued: 'node-3@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 60181
*** User 2017-05-05 20:39:47.460 ***
Joining node: 'node-2@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 60165
*** User 2017-05-05 20:39:47.461 ***
Joining issued: 'node-2@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 60165
*** User 2017-05-05 20:39:47.461 ***
Joining node: 'node-1@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 60152
*** User 2017-05-05 20:39:47.462 ***
Joining issued: 'node-1@MacBook-Pro-de-Anne-France' to 'runner@MacBook-Pro-de-Anne-France' at port 60152
*** User 2017-05-05 20:39:47.523 ***
Waiting for join to complete with manager: partisan_default_peer_service_manager
*** User 2017-05-05 20:39:47.524 ***
Finished.
*** CT 2017-05-05 20:39:47.524 *** COVER INFO
Adding nodes to cover test: ['runner@MacBook-Pro-de-Anne-France']
*** CT 2017-05-05 20:39:47.533 *** COVER INFO
Successfully added nodes to cover test: []
*** User 2017-05-05 20:39:47.533 ***
Case finished: uncontracted_latency_test
*** User 2017-05-05 20:39:54.578 ***
20:39:54.578 [info] Application lasp exited with reason: stopped
*** User 2017-05-05 20:39:54.579 ***
20:39:54.579 [info] Application partisan exited with reason: stopped
=== Ended at 2017-05-05 20:39:54
=== successfully completed test case
=== Returned value: ok
Test run history
| Top level test index


HTML Attributes contents
Anchor
Images
White Space text a multiple line
break
paragragh
content
Inline/ Block
inline
text
Span / div
HTML documents
HTML title CSS JS
contents
What is a Web Page
A web page is a text document written in a language called HTML. Web browsers read these documents, and then interpret and display them.


{% extends '../base.html' %} {% include '../menus/project.html' %} {% block title %} Delete {% end %} {% block main %}
Delete a project's settings, queues, and results.
This is very dangerous as the project settings contains metadata needed to reconstruct the URLs. Please proceed only if you are sure the URLs are correctly published and archived.
{% module Form(form, submit='Delete') %} {% end %}


Posted by ilake on June 3, 2017
Posted by ilake on May 20, 2017
Posted by ilake on May 13, 2017
Posted by ilake on May 6, 2017
Posted by ilake on April 15, 2017
Posted by ilake on April 8, 2017
Posted by ilake on April 1, 2017
Posted by ilake on March 25, 2017
Posted by ilake on March 18, 2017
Posted by ilake on March 11, 2017
c'est la vie'


cproj
, cprojf
— Riemann sphere projection#include <complex.h> double complex cproj(double complex z); float complex cprojf(float complex z);
Description
These functions compute a projection of z onto the Riemann
sphere: z projects to z except that all complex infinities
(even those with one infinite part and one NaN part) project
to positive infinity on the real axis. If z has an infinite part,
then cproj
(z) is equivalent to
INFINITY + I * copysign(0.0, cimag(z))
cprojf
is identical to cproj
, except that it performs
its calculations on floats complex
.
Returns
Portability
cproj
and cprojf
are ISO C99


--- layout: splash classes: - landing - dark-theme --- {% include feature_row id="intro" type="center" %} {% include feature_row %} {% include feature_row id="feature_row2" type="left" %} {% include feature_row id="feature_row3" type="right" %} {% include feature_row id="feature_row4" type="center" %}


Android Development Trial
TL;DR
I learnt some of the Android approaches that I missed in the projects I've been working on, such as I18n, at the same time, I also find that the documentation of Android is kind of terrible, especially when you only want to use the latest version of Android APIs without backward compatibility.
After finish this little A humanitarian APP against sound activated light switches in some scenes app, I found that, even though I've got the functionalities I want, however, I wasn't in the correct way of doing Android development, for example, I didn't use the layouts and components properly.. will do better maybe the next time :P
About 2 months ago, when I was on vacation, I spent about 5 days (say 8 work hrs/day) to try Android development, for fun, and, of course, for some benifits.
The app is named "Cry for Light", which is "A humanitarian APP against sound activated light switches in some scenes". Literally, it cries when the brightness is low :P
Why should this app exist?
The Story
The story starts from that our company replaced some light switches of the pantries to sound activated light switches.
In the pantries, there're several water coolers, to provide cool and especially hot water, and in one of the pantries, there are some tables for having meals, along with a foosball table (that's great!).
As you probably have been aware of, it definitely takes sometime to fulfill a bottle with hot water, and takes more time to finish a meal or play foosball.
Unfortunately, the new lights will only be triggered by a relatively louder voice, and then keep on for about 1 minitue or so. They're going to be off anyway before the next turning on, even if the loud voice is still there… (great job right?)
Hence if one washes one's cup before fulfill hot water, it's highly likely the light will be off during fulfilling the hot water, after the light is off, we can barely see things, so the hot water might run out of one's cup if one don't stop at the proper time… sounds dangerous right?
That would be even better if you're in a queue to wash your cup or fulfill water, not to mention the dinner or foosball stuff..
OK, even we're in such a smart company, as a developer, we should make our own lives easy, right?
Thus, the requirements are really straightforward: since we have smartphones with light sensors and speakers, why not just monitor the brightness of the env and play sound once it turns dark? As long as it turns dark anyway…
Learn Android Development
I was thinking to develop a web app + using Chrome routine, but just accidently found some Android materials, so why not I try something new? A bonus that I was using Nexus 5X :P
The Android development toolchains are awesome now, I mean the Android Studio turned from eclipse-based to intellij-idea-based. I got the env set up in my MacBook really easily.
As I didn't really want to dig into Android development, I decided to support Android 6+ on Nexus 5X only, so that it would be easier and quicker to get started and achieve my goals, however, when I went to the documentation, I was kind of lost: how can I find the complete set of APIs/Components I need, specifically the Android approaches using only the latest APIs?
If you've seen the documentation of Android, you'll find that apart from the basic concepts, most of the examples are kind of backward compatible. That's great, for the others, but not for me. I don't really want the v7 appcompact
lib or v4 appcompact
lib, I only want the latest!
Yes I can use the latest libs only anyway, but then the documentation becomes less helpful and harder to find what a new android developer need… that's the terrible part…
What I learn
I learnt the basic concepts such as intents, activities, services, learnt how to layout and use the assets, learnt how to use notifications and perferences… a lot of Android fundamentals (even though I've forgotten a lot of them now LOL), but the most impressive part may be how Android works with the resources.
In my previous work projects, I don't think we worried a lot about Theme, I18n, Responsive(i.e layouts and different image assests for different views), and an important one, Performance. We didn't do a lot of Test too… sounds bad :(
In Android, it suggests that one should always externalise the strings, numbers or other values, for easier I18n and more, and by doing that, say externalise the colours, one can change the colour scheme very easily.
Android also provides a mechanism to load different resources for different devices (DPI, screen size or so). This is a non-trivial part of improving the user experiences on mobile devices. Responsive is always mentioned by our team, but rarely turned into practices.
Another important reminder is the Performance. In the guide of Android, it always highlights what should be considered in order to improve the performance. Such as should not leave a service running whenever unnecessary.
After reading the parts related to performance, I finally understand why my phone is so slow after installed a lot of Chinese Android apps, even though I don't open a lot by myself.
Most of Chinese apps are doing really great job to always keep their services UP, which occupy a lot of memory of the device.
Regarding the performance, even though our devices are getting better and better nowadays, we should not rely on that "the user devices should be capable for that", since if the developers of every app think like the same, our devices are dying anyway…
Well…
Actually, I also learnt that I should focus more on what I'm doing, web development, and improve my shortages such as mobile web, performance, responsive, in order to make some really good apps :P


Catherine is a 3rd Year Psychology student and her hobbies include drumming and video games.
Catherine is a 3rd Year Psychology student and her hobbies include drumming and video games.
Sinead is a 3rd Year PPE student enjoys cooking and reading in her free time.
Sithara is also a PPE student in her 3rd Year and likes to read or bake in her free-time.
Traditional German Cooking is very steamy, heavy and yummy! Lots of carbs and meat - but don't worry - you can get around that with a few tricks, if that isn't for you. Have a look at our recipes for traditional German Food and their variations and let us know, which one you liked best.
A bit of a messy food to prepare and cook, it makes up for it by having only 3 ingredients and turning out to be one of the best pasta on continental Europe (and maybe the world)!
Prep time: 10 mins
Cooking time: 10 mins
Ingredients:
A dish that is not necessarily everyone's fave, but definitely at the top of typical German winter dinners is Grünkohl und Pinkel. You can find a stand selling it at everychristmas market. And though I wasn't a fan of it as a child, by now I've gotten used to the very special taste and my mum even makes it at home occasionally.
It is easiest to just buy the sausages, but if you wanna give making them yourself a go check this our: https://www.essen-und-trinken.de/rezepte/44069-rzpt-gruenkohl-mit-pinkel.
Prep time: 10 mins
Cooking time: 2 1/2 hours
Ingredients:
And it's ready! It usually eaten by itself or with cooked potatoes that are roasted after and/or very lightly caramelized.
Probably the only dish on this list that is not exactly traditionally German, it is a traditional family dish. If you love pasta and tomato sauce or ketchup, this one's for you and it can feed you for days!
Prep time: 5 mins
Cooking time: 20 mins
Ingredients:


Event Registration
{% csrf_token %}
Event name :
Location :
Link of poster:
From :
To :
Reg. Deadline :
Email id :
Host password :
Description :
Submit
Back to HomePage


Supvisors uses the Supervisor's XML-RPC API extension facility to add behaviour into Supervisor.
More particularly, Supvisors starts a dedicated thread inside the supervisord daemon to perform the additional work.
This part presents the main structures used in the python source code of Supvisors.
Each program controlled by Supervisor is represented in a class called ProcessStatus
.
More particularly, it contains the following information:
ProcessStatus | |
|---|---|
application_name | name of the application that the process belongs to, in other words the Supervisor group |
process_name | name of the process, in other words the Supervisor program name |
state | 'synthetic' state of the process, as defined in Supervisor |
expected_exit | status telling if the process has exited as expected, only makes sense when state is EXITED |
last_event_time | date of the last process event received from Supervisor, in remote reference time |
addresses | set of addresses where the process is in a RUNNING state0 or 1 value is expected if more that one value, a split-brain syndrome is happening |
processes | map of process information, key is address |
rules | a ProcessRules instance containing the deployment model of the process, as defined in the rules file |
Supervisor defines the following lists of states:
STOPPED_STATES = (ProcessStates.STOPPED,
ProcessStates.EXITED,
ProcessStates.FATAL,
ProcessStates.UNKNOWN)
RUNNING_STATES = (ProcessStates.RUNNING,
ProcessStates.BACKOFF,
ProcessStates.STARTING)
Note about the state synthesis of a process
The state of the ProcessStatus
is a kind of synthesis based on the states declared on all Supervisor instances.
Depending on how the program has been used on different addresses, it may be STOPPED
on address A, EXITED
on address B,
RUNNING
on address C, etc.
So Supvisors uses the following priority to declare the process state:
RUNNING_STATES
, with RUNNING
> BACKOFF
> STARTING
,STOPPING
state,STOPPED_STATES
.Note about the decision not to use the Subprocess
class, available in Supervisor source code
First, it may be impossible to point to the Subprocess
reference in supervisord config, as it may not exist.
Although it is recommended for the usage of Supvisors, nothing forces the user to configure all the Supervisor instances with exactly the same list of programs.
So when receiving a process event in the Supvisors instance B (i.e. located on address B), coming from the Supvisors instance A,
it may happen that the involved process is unknown to the Supervisor instance hosting B.
So, considering that a new instance of a Subprocess
could be handled in Supvisors, that raises other problems.
For the same reason given above, it may be impossible to assign a config to this instance. In addition to that, as a different instance of the same program
may be managed by every Supvisors instances, there is no guarantee that the process state transitions will be fully respected. Supvisors has to juggle with that.
Finally, Subprocess
methods and most of the information held are irrelevant to Supvisors.
Note about the process information
The process information held in Supvisors looks more or less like the dictionary got from
the supervisor.getProcessInfo
XML-RPC.
A few entries are removed from this dictionary, because they are useless in Supvisors and in order to improve performance: description
, stderr_logfile
, stdout_logfile
, logfile
, exitstatus
.
A few entries are added to this dictionary: localTime
, eventTime
, uptime
, expected
.
The dictionary contents are still subject to modifications.
| Key | Value |
|---|---|
'name' | name of the process |
'group' | name of the group, i.e. name of the application for Supvisors |
'description' | description of the process activity |
'start' | start time of the process, in remote reference time |
'stop' | stop time of the process, in remote reference time |
'now' | current time of the process, in remote reference time |
'local_time' | current time of the process, in local reference time |
'event_time' | date of the last event received, in local reference time |
'uptime' | age of the process |
'state' | state of the process |
'statename' | state of the process, as string |
'spawnerr' | error description when process cannot be spawned |
'exitstatus' | exit code of the process |
'expected' | expected exit of the process (true, false) |
'logfile' | standard ouput of the process, deprecated |
'stdout_logfile' | standard ouput of the process |
'stderr_logfile' | error ouput of the process |
'pid' | process identifier |
A ProcessStatus
belongs to an ApplicationStatus
.
More particularly, it contains the following information:
ApplicationStatus | |
|---|---|
application_name | name of the application, in other words the Supervisor group |
state | state of the application, among:
|
major_failure | indicates a required process is in FATAL state or is unexpectedly EXITED .In this case, the application is not operational. |
minor_failure | indicates an optional process is in FATAL state or is unexpectedly EXITED .this status should not affect the operational status of the application. |
processes | map of ProcessStatus instances.key is process_name . |
rules | an ApplicationRules instance containing
the deployment model of the application, as defined in the rules file |
Each local Supvisors instance has its own perception of other remote Supvisors instance. This perception is stored in a class called AddressStatus
.
More particularly, it contains the following information:
AddressStatus | |
|---|---|
address_name | address of the Supvisors instance |
state | state of the Supvisors instance, among:
|
remote_time | date of the last heartbeart received in remote reference time |
local_time | date of the last heartbeart received in local reference time |
Every time that a Supvisors instance becomes RUNNING
, the local Supvisors instance gets and stores all process information from the Supervisor daemon using
the supervisor.getAllProcessInfo
XML-RPC.
Supvisors uses the python module supervisor.options
to determine the location of the configuration file and to parse it.
from supervisor.options import Options, UnhosedConfigParser
# get supervisord.conf file from search paths
options = Options(True)
configfile = options.default_configfile()
# parse file
parser = UnhosedConfigParser()
parser.read(configfile)
parser.mysection = 'supvisors'
As Supervisor has a dependency with xml.etree.ElementTree
, this module has naturally been used
to parse the rules file.
Unfortunately, this module does not provide any schema validation. So, if the module lxml.etree
is available,
it is used instead of the ElementTree module to validate and parse the XML deployment.
More information about the lxml XML toolkit can be found here.
The contents of the XSD can be found in the module supvisors.parser
.
If pushed to a file, it can be used to validate the XML file with such a shell command:
[bash] > xmllint --noout --schema etc/deployment.xsd etc/deployment.xml
Supvisors uses the python module supervisor.loggers
for logging.
from supervisor.loggers import getLogger
LOGGER_FORMAT = '%(asctime)s %(levelname)s %(message)s\n'
stdout = supervisord.options.nodaemon
logger = getLogger(logfile, loglevel, LOGGER_FORMAT, True, logfile_maxbytes, logfile_backups, stdout)
As Supvisors runs inside Supervisor, it makes it possible to collect events directly by subscribing to supervisor.events
instead of using an event listener program.
from supervisor import events
events.subscribe(events.SupervisorRunningEvent, self.on_running)
events.subscribe(events.SupervisorStoppingEvent, self.on_stopping)
events.subscribe(events.ProcessStateEvent, self.on_process)
events.subscribe(events.Tick5Event, self.on_tick)
Upon notification of the events.SupervisorRunningEvent
event, the main loop thread of the Supvisors instance is started.
This thread could not be started before (when extending Supervisor XML-RPC) because it would stop if supervisord daemonizes.
Upon notification of the events.SupervisorStoppingEvent
event, the main loop thread of the Supvisors instance is stopped.
Supvisors creates a heartbeat message upon notification of the events.Tick5Event
events.
The date event.when
is used to fill this message.
Upon notification of the events.ProcessStateEvent
events, Supvisors creates a message with the following contents:
| Key | Value |
|---|---|
'processname' | name of the process |
'groupname' | name of the group, i.e. name of the application for Supvisors |
'state' | new state of the process, as a ProcessStates value, obtained from the event type |
'now' | reception time of the process event |
'pid' | UNIX process identifier (only when state is RUNNING , STOPPING ,
STOPPED or EXITED ) |
'expected' | boolean indicating if the exit status is expected (only when state is EXITED ) |
The messages are published using a ZeroMQ PUBLISH socket over a TCP socket bound on the internal_port defined in the Supervisor configuration file. They are sent in two parts:
(localAddress, payload)
, where payload is the event contents,
serialized with pickle (provided by PyZMQ).# example of sending Tick event
self.socket.send_string(u'tick', zmq.SNDMORE)
self.socket.send_pyobj((addressMapper.localAddress, payload))
Note about the localAddress
When starting, the Supvisors instance has to determine its identity. More particularly, it has to find its own address among the list defined in
the address_list
option of the [supvisors]
section in the Supervisor configuration file.
So, the Supvisors instance gets the host name and all known IPv4 addresses of the host where it is running, excluding the loopback address.
It is expected that one element of this list MUST be an element of the address_list
.
This element becomes the localAddress.
In Supvisors' main loop, a ZeroMQ SUBSCRIBE socket is built over a TCP socket connected to all addresses found
in address_list
on the internal_port
defined in the Supervisor configuration file.
The Supvisors main loop polls the Supvisors events coming from all addresses through this socket with a timeout of one second.
Tick events are used to update the status of the AddressStatus
instances.
ProcessState events are used to update the status of the ProcessStatus
instances and consequently
the related ApplicationStatus
instances.
The timeout of the ZeroMQ poller in the Supvisors main loop is used to trigger a periodic task (every 5 seconds). This task is used to check the activity of the Supvisors instances and to trigger the Supvisors Machine State.
The periodic task performs a verification over all the heartbeat of every Supvisors intances.
When the last heartbeat message received is older than 10 seconds, Supvisors set the state of the AddressStatus
instance to:
SILENT
if auto-fencing is not activated,ISOLATING
if auto-fencing is activated,The corresponding address is then removed from all the addresses
sets in the ProcessStatus
instances,
which leads to a temporary inconsistence as the processes may be declared RUNNING
nowhere.
The next phase consists in restarting the process somewhere else, if possible, using the deployment function of Supvisors.
Finally, if the AddressStatus
instance was marked ISOLATING
,
Supvisors diconnects the corresponding url from the ZeroMQ SUBSCRIBE socket and sets the state to ISOLATED
.
If the state is SILENT
, Supvisors will accept the remote Supvisors instance to come back.
During the periodic task, the context of the Supvisors instance is re-evaluated.
The State Machine of the Supvisors instance deals with the following states: INITIALIZATION
, DEPLOYMENT
,
OPERATION
, CONCILIATION
, RESTARTING
, SHUTTING_DOWN
, SHUTDOWN
.
In the INITIALIZATION
state, Supvisors waits for all Supvisors instances to be active.
More particularly, heartbeat messages (or Tick events) are expected for every entry in the address_list
.
INITIALIZATION state | |
|---|---|
The state of all AddressStatus instances is reset to UNKNOWN .Exception is made for instances that are in ISOLATED state. Once a AddressStatus instance has been isolated,
it is impossible to come back in any other state, so they remain in this state. |
|
Supvisors waits until synchro_timeout seconds for all Supvisors instances to be active.
As soon as the related AddressStatus instances are all RUNNING , Supvisors transitions to DEPLOYMENT state.If some AddressStatus instances are still in an UNKNOWN state after that delay,
Supvisors declares them SILENT (or ISOLATING if auto_fencing is activated) and transitions to DEPLOYMENT state with a degraded situation. |
|
| A Master is elected among the active Supvisors instances. It has been arbitrarily decided to choose the lowest address, from a 'string' point of view. |
Note about the concept of "Master"
It is necessary to choose a Master among the active Supvisors instances because only one of them will be in charge of:
In the DEPLOYMENT
state, Supvisors performs an automatic deployment of the applications in accordance with the rules
defined in the rules file and with the resources available, i.e. the set of addresses having an active Supvisors intance.
DEPLOYMENT state | |
|---|---|
| Supvisors plans the sequencing of the deployment, at the application level, in accordance with the process information loaded from
the remote Supersivor and the sequencing defined in the rules file.
As told before, nothing forces the user to configure Supervisor with the same list of programs on every addresses.
The sequencing has thus to take into account the actual list of programs that has been loaded from the active Supvisors instances. The deployment starts. The principles of the function are detailed hereafter. |
|
| The deployment progress is checked and the next phase is triggered if any. When the job is done, Supvisors transitions to the OPERATION state, unless a conflict is detected.
In this case, Supvisors transitions to the CONCILIATION state. |
|
| no action |
Note about the unicity of the processes
Although the same program definition may be loaded into the different Supervisor instances, Supvisors ensures that a single process
may be running among them at the same time. Of course, as the Supervisor functions are still available (through supervisorctl or ini file definitions),
it is easy to trick Supvisors so that multiple processes are running on several addresses.
Supvisors considers this situation, that is typically a case of split-brain, as a conflict and handles it
in the CONCILIATION
state.
When the user really needs several instances of the same program to be running on different addresses, the solution is to set
the Supervisor numprocs
option accordingly in the program definition.
In the OPERATION
state, Supvisors checks the activity of the Supvisors instances and detects the eventual conflicts.
OPERATION state | |
|---|---|
| no action | |
If the Master becomes inactive, Supvisors needs a new Master to be elected and transitions to the INITIALIZATION state.When a conflict is detected, Supvisors transitions to the CONCILIATION state. |
|
| no action |
In the CONCILIATION
state, Supvisors applies a strategy to solve the detected conflicts and waits until they are done.
In this state, the Supvisors XML-RPC dealing about starting applications or processes are ineffective but it has no impact on the Supervisor XML-RPC, that are still available.
CONCILIATION state | |
|---|---|
The conciliation strategy set through the conciliation_strategy option is applied.The principles of the function are detailed hereafter. |
|
If the Master becomes inactive, Supvisors needs a new Master to be elected and transitions to the INITIALIZATION state.When a conflict is solved, Supvisors transitions back to the OPERATION state. |
|
| no action |
The RESTARTING
state can be reached from DEPLOYMENT
, OPERATION
and CONCILIATION
states, using a XML_RPC request.
In this state, Supvisors performs an automatic stop of all applications in accordance with the rules defined
in the rules file before a full restart.
RESTARTING state | |
|---|---|
| Supvisors plans the stopping of the applications, in accordance with the sequencing defined in the rules file and starts to stop the running processes. | |
| The stopping progress is checked and the next phase is triggered if any. When the job is done, Supvisors transitions to the SHUTDOWN state. |
|
| Supvisors triggers its full restart through the restart of all Supervisor instances. |
The SHUTTING_DOWN
state can be reached from DEPLOYMENT
, OPERATION
and CONCILIATION
states, using a XML_RPC request.
In this state, Supvisors performs an automatic stop of all applications in accordance with the rules defined
in the rules file before a full shutdown.
SHUTTING_DOWN state | |
|---|---|
| Supvisors plans the stopping of the applications, in accordance with the sequencing defined in the rules file and starts to stop the running processes. | |
| The stopping progress is checked and the next phase is triggered if any. When the job is done, Supvisors transitions to the SHUTDOWN state. |
|
| Supvisors triggers its full shutdown through the shutdown of all Supervisor instances. |
The SHUTDOWN
state is the final state. No action is performed.
Once that Supvisors is ready to work, the starting and stopping sequences are established.
Starting and stopping applications follow the same principle.
To start applications, Supvisors creates a job list and performs the following loop until there is nothing left to do:
deployment_strategy
optionsupvisors.start_args
XML-RPC to the Supervisor located on that addressRUNNING
Whatever the strategy applied, there are common rules to choose an address to start a process:
address_list
defined in the Supvisors section of the Supervisor configuration file,addresses
defined in the program section of the rules file,AddressStatus
representing this address shall be in RUNNING
state,loading
values associated to the program considered and to all processes that are currently running on the address considered shall not exceed 100%.When applying the CONFIG
strategy, Supvisors chooses the first address in the addresses
list that respects the common rules.
When applying the LESS_LOADED
strategy, with respect of the common rules, Supvisors chooses the address in the addresses
list having the lowest loading sum.
The aim is to distribute the process loading among the available hosts.
When applying the MOST_LOADED
strategy, with respect of the common rules, Supvisors chooses the address in the addresses
list having the greatest loading sum.
The aim is to maximize the load of a host before starting to load another host. This strategy is more interesting when the resources are limited.
To stop applications, Supvisors creates a job list and performs the following loop until there is nothing left to do:
supervisor.stopProcess
XML-RPC to the Supervisor located on that addressSTOPPED
When Supervisor fails to start a process upon request, due to a problem of configuration, the process remains in STOPPED
state.
In Supvisors, it is considered as a major failure. So, the Supervisor internal Subprocess
instance is tricked, so that an event is fired by Supervisor and the process becomes FATAL
with an adequate spawnerr
description.
subProcess = supervisord.process_groups[applicationName].processes[processName]
# need to force BACKOFF state to go through assertion
from supervisor.states import ProcessStates
subProcess.state = ProcessStates.BACKOFF
subProcess.spawnerr = reason
subProcess.give_up()
The same principle has been used to set a major failure to the process if Supvisors fails to find an address where it could be started, due to a lack of resources.
When more than one instance of the same program are running in different Supervisor daemons, it is considered as a conflict in Supvisors
When applying the SENICIDE
strategy, Supvisors keeps the youngest process, i.e. tha process that has been started the most recently, and stops all the others.
When applying the INFANTICIDE
strategy, Supvisors keeps the oldest process and stops all the others.
When applying the USER
strategy, Supvisors just waits that a user aplication solves the conflicts using supervisorctl
, XML-RPC, process signal, or any other solution.
When applying the STOP
strategy, Supvisors stops all conflicting processes.
When applying the RESTART
strategy, Supvisors stops all conflicting processes and restarts a new one.
The process events received in the main loop are re-published using a ZeroMQ PUBLISH socket over a TCP socket locally bound on the event_port
defined in the Supervisor configuration file. The body is serialized with json instead of pickle (also provided by PyZMQ).
Note about the Supvisors Event Interface
This is a local publication (bound on localhost). An applicative process can only subscribe to its co-located Supvisors instance.
It has been considered to use a supervisor.sendProcessStdin
XML-RPC to send events to applicative program but it would have too much impact on the user applicative design.
The extension point provided in Supervisor configuration file adds a plugin to the existing supervisord XML-RPC API.
The RPCInterface
class in the module supvisors.rpcinterface
follows the same principles as the SupervisorNamespaceRPCInterface
class in the module supervisor.rpcinterface
.
In order to benefit from the Supervisor handling in case of exception, the Faults
class of the supervisor.xmlrpc
module is dynamically extended with the following SupvisorsFaults
values:
SUPVISORS_CONF_ERROR=100,
BAD_SUPVISORS_STATE=101,
BAD_ADDRESS=102,
BAD_STRATEGY=103
Supvisors uses the HTTP server created by Supervisor but replaces the main page. This is done by modifying dynamically the contents of the VIEWS
dictionary in the module supervisor.web
.
from supervisor.web import VIEWS
here = path.abspath(path.dirname(__file__))
# set main page
VIEWS['index.html'] = { 'template': path.join(here, 'ui/index.html'), 'view': SupvisorsView }
# set address page
VIEWS['address.html'] = { 'template': path.join(here, 'ui/address.html'), 'view': AddressView }
# set application page
VIEWS['application.html'] = { 'template': path.join(here, 'ui/application.html'), 'view': ApplicationView }
# set fake page to export images
VIEWS['process_stats.png'] = { 'template': path.join(here, 'ui/empty.html'), 'view': ProcessImageView }
VIEWS['address_stats.png'] = { 'template': path.join(here, 'ui/empty.html'), 'view': AddressImageView }
The last two 'pages' are used to publish the contents of an image generated by matplotlib through the HTTP server, and without writing anything on disk.
The extension point provided in Supervisor configuration file adds a plugin to the existing supervisorctl.
The ControllerPlugin
class in the module supvisors.supervisorctl
was inspired by the DefaultControllerPlugin
class in the module supervisor.supervisorctl
.


Search
Sign In
Cart
IND
Products
Solutions
Services
Support
Deals
Find a Store
{% for link in result %}
{% endfor %}


Today's Specials
- Flaming Hummus & Falafel Salad
- Sizzling Bean Burrito
- Green Gloves Tamales
Our wesome Reviews
"I got so excited about the yumminess of the falafel salad that I am typing this review as I inhale my lunch. Yes, it is that good... Service was super friendly and quick. Can't wait to see you Rogue Pickings again tomorrow."
Contact Us
1001 Potrero Avenue
San Francisco, CA 94110
(415) 206-8000


IPL: Persepolis and Sepahan both held [VIDEO]
by Mir Farhad Ali KhanTasnim – TEHRAN, Persepolis and Sepahan football teams were held by their opponents in Matchday 9 of Iran Professional League (IPL) on Thursday.
Persepolis drew 0-0 with Machine Sazi in Tehran’s Azadi Stadium.
Persepolis forward Ali Alipour missed a penalty in 90th penalty.
In Abadan, Pars Jonoubi and Sepahan shared the spoils. Reza Esmaeili gave a lead the visiting team and Pars Jonoubi captain Mohammad Nouri equalized the match before the interval.
Naft Masjed Soleyman and Foolad played out a goalless draw in Masjed Soleyman.
Nassaji Mazandaran was held to a 0-0 draw by Sanat Naft.
And Shahr Khodro Mashhad also drew 0-0 with Saipa in Tehran.


IndexOf Method
Returns the index at which value can be found in the array, or -1 if value is not present in the array
Inputs :
Employees Salary
Finde in 30000 salary Employee
Using JS :
Using Underscore.Js :


Reliance Capital share price locked in lower circuit on payment delay
There were pending sell orders of 137,672 shares, with no buyers available.
by Moneycontrol NewsReliance Capital shares were locked in 5 percent lower circuit on November 20 after the company delayed payment of interest on non-convertible debentures.
The payment interest/ principal obligations on the non-convertible debenture due on November 18, 2019, had been delayed, the company said in a press release.
The company's shareholding in its wholly owned subsidiary, Reliance General Insurance Company (RGIC), has been transferred to IDBI Trustee Services Limited, upon invocation of pledge by the Trustee, the company said in another release.
The company was trying to monetise its shareholding in RGIC as part of its plan for debt reduction.
The company would take all appropriate steps in the matter as legally advised to protect the interests of its lenders and other stakeholders, it added.
There were pending sell orders of 137,672 shares, with no buyers available.
At 0940 hours, Reliance Capital was quoting at Rs 18.05, down Rs 0.95, on the BSE.


I was a fool to trust you with such an important errand!  Get out of my sight, right now!!!


Please answer our Rent Contract.
The House of Cars family wishes you a comfortable and enjoyable drive, We will leave you some tips for a safe driving .
Sign in the canvas below and save your signature as an image!


Apache DistributedLog Release Guide
- Apache DistributedLog Release Guide
This page documents the procedure to make an Apache DistributedLog release. Credit to the Beam project. We’ve borrow liberally from their documentation.
Introduction
The Apache DistributedLog project periodically declares and publishes releases. A release is one or more packages of the project artifact(s) that are approved for general public distribution and use. They may come with various degrees of caveat regarding their perceived quality and potential for change, such as “alpha”, “beta”, “incubating”, “stable”, etc.
The DistributedLog community treats releases with great importance. They are a public face of the project and most users interact with the project only through the releases. Releases are signed off by the entire DistributedLog community in a public vote.
Each release is executed by a Release Manager, who is selected among the DistributedLog committers. This document describes the process that the Release Manager follows to perform a release. Any changes to this process should be discussed and adopted on the dev@ mailing list.
Please remember that publishing software has legal consequences. This guide complements the foundation-wide Product Release Policy and Release Distribution Policy.
Overview
The release process consists of several steps:
- Decide to release
- Prepare for the release
- Build a release candidate
- Vote on the release candidate
- If necessary, fix any issues and go back to step 3.
- Finalize the release
- Promote the release
Decide to release
Deciding to release and selecting a Release Manager is the first step of the release process. This is a consensus-based decision of the entire community.
Anybody can propose a release on the dev@ mailing list, giving a solid argument and nominating a committer as the Release Manager (including themselves). There’s no formal process, no vote requirements, and no timing requirements. Any objections should be resolved by consensus before starting the release.
In general, the community prefers to have a rotating set of 3-5 Release Managers. Keeping a small core set of managers allows enough people to build expertise in this area and improve processes over time, without Release Managers needing to re-learn the processes for each release. That said, if you are a committer interested in serving the community in this way, please reach out to the community on the dev@ mailing list.
Checklist to proceed to the next step
- Community agrees to release
- Community selects a Release Manager
Prepare for the release
Before your first release, you should perform one-time configuration steps. This will set up your security keys for signing the release and access to various release repositories.
To prepare for each release, you should audit the project status in the JIRA issue tracker, and do necessary bookkeeping. Finally, you should create a release branch from which individual release candidates will be built.
One-time setup instructions
GPG Key
You need to have a GPG key to sign the release artifacts. Please be aware of the ASF-wide release signing guidelines. If you don’t have a GPG key associated with your Apache account, please create one according to the guidelines.
Determine your Apache GPG Key and Key ID, as follows:
gpg --list-keys
This will list your GPG keys. One of these should reflect your Apache account, for example:
--------------------------------------------------
pub 2048R/845E6689 2016-02-23
uid Nomen Nescio<EMAIL_ADDRESS>sub 2048R/BA4D50BE 2016-02-23
Here, the key ID is the 8-digit hex string in the pub
line: 845E6689
.
Now, add your Apache GPG key to the DistributedLog’s KEYS
file both in dev
and release
repositories at dist.apache.org
. Follow the instructions listed at the top of these files.
Configure git
to use this key when signing code by giving it your key ID, as follows:
git config --global user.signingkey 845E6689
You may drop the --global
option if you’d prefer to use this key for the current repository only.
You may wish to start gpg-agent
to unlock your GPG key only once using your passphrase. Otherwise, you may need to enter this passphrase hundreds of times. The setup for gpg-agent
varies based on operating system, but may be something like this:
eval $(gpg-agent --daemon --no-grab --write-env-file $HOME/.gpg-agent-info)
export GPG_TTY=$(tty)
export GPG_AGENT_INFO
Access to Apache Nexus repository
Configure access to the Apache Nexus repository, which enables final deployment of releases to the Maven Central Repository.
- You log in with your Apache account.
- Confirm you have appropriate access by finding
org.apache.distributedlog
underStaging Profiles
. - Navigate to your
Profile
(top right dropdown menu of the page). - Choose
User Token
from the dropdown, then clickAccess User Token
. Copy a snippet of the Maven XML configuration block. -
Insert this snippet twice into your global Maven
settings.xml
file, typically${HOME}/.m2/settings.xml
. The end result should look like this, whereTOKEN_NAME
andTOKEN_PASSWORD
are your secret tokens:<settings> <servers> <server> <id>apache.releases.https</id> <username>TOKEN_NAME</username> <password>TOKEN_PASSWORD</password> </server> <server> <id>apache.snapshots.https</id> <username>TOKEN_NAME</username> <password>TOKEN_PASSWORD</password> </server> </servers> </settings>
Website development setup
Get ready for updating the DistributedLog website by following the website development instructions.
Create a new version in JIRA
When contributors resolve an issue in JIRA, they are tagging it with a release that will contain their changes. With the release currently underway, new issues should be resolved against a subsequent future release. Therefore, you should create a release item for this subsequent release, as follows:
- In JIRA, navigate to the
DistributedLog > Administration > Versions
. - Add a new release: choose the next minor version number compared to the one currently underway, select today’s date as the
Start Date
, and chooseAdd
.
Triage release-blocking issues in JIRA
There could be outstanding release-blocking issues, which should be triaged before proceeding to build a release candidate. We track them by assigning a specific Fix version
field even before the issue resolved.
The list of release-blocking issues is available at the version status page. Triage each unresolved issue with one of the following resolutions:
- If the issue has been resolved and JIRA was not updated, resolve it accordingly.
- If the issue has not been resolved and it is acceptable to defer this until the next release, update the
Fix Version
field to the new version you just created. Please consider discussing this with stakeholders and the dev@ mailing list, as appropriate. - If the issue has not been resolved and it is not acceptable to release until it is fixed, the release cannot proceed. Instead, work with the DistributedLog community to resolve the issue.
Review Release Notes in JIRA
JIRA automatically generates Release Notes based on the Fix Version
field applied to issues. Release Notes are intended for DistributedLog users (not DistributedLog committers/contributors). You should ensure that Release Notes are informative and useful.
Open the release notes from the version status page by choosing the release underway and clicking Release Notes.
You should verify that the issues listed automatically by JIRA are appropriate to appear in the Release Notes. Specifically, issues should:
- Be appropriately classified as
Bug
,New Feature
,Improvement
, etc. - Represent noteworthy user-facing changes, such as new functionality, backward-incompatible API changes, or performance improvements.
- Have occurred since the previous release; an issue that was introduced and fixed between releases should not appear in the Release Notes.
- Have an issue title that makes sense when read on its own.
Adjust any of the above properties to the improve clarity and presentation of the Release Notes.
Create a release branch
Release candidates are built from a release branch. As a final step in preparation for the release, you should create the release branch, push it to the code repository, and update version information on the original branch.
Check out the version of the codebase from which you start the release. For a new minor or major release, this may be HEAD
of the master
branch. To build a hotfix/incremental release, instead of the master
branch, use the release tag of the release being patched. (Please make sure your cloned repository is up-to-date before starting.)
git checkout <master branch OR release tag>
Set up a few environment variables to simplify Maven commands that follow. (We use bash
Unix syntax in this guide.)
VERSION="0.4.0-incubating"
NEXT_VERSION="0.5.0"
BRANCH_NAME="release-${VERSION}"
DEVELOPMENT_VERSION="${NEXT_VERSION}-SNAPSHOT"
Version represents the release currently underway, while next version specifies the anticipated next version to be released from that branch. Normally, 0.4.0 is followed by 0.5.0, while 0.4.0 is followed by 0.4.1.
Use Maven release plugin to create the release branch and update the current branch to use the new development version. This command applies for the new major or minor version. (Warning: this command automatically pushes changes to the code repository.)
mvn release:branch \
-DbranchName=${BRANCH_NAME} \
-DdevelopmentVersion=${DEVELOPMENT_VERSION}
However, if you are doing an incremental/hotfix release, please run the following command after checking out the release tag of the release being patched.
mvn release:branch \
-DbranchName=${BRANCH_NAME} \
-DupdateWorkingCopyVersions=false \
-DupdateBranchVersions=true \
-DreleaseVersion="${VERSION}-SNAPSHOT"
Check out the release branch.
git checkout ${BRANCH_NAME}
The rest of this guide assumes that commands are run in the root of a repository on ${BRANCH_NAME}
with the above environment variables set.
Checklist to proceed to the next step
- Release Manager’s GPG key is published to
dist.apache.org
- Release Manager’s GPG key is configured in
git
configuration - Release Manager has
org.apache.distributedlog
listed underStaging Profiles
in Nexus - Release Manager’s Nexus User Token is configured in
settings.xml
- JIRA release item for the subsequent release has been created
- There are no release blocking JIRA issues
- Release Notes in JIRA have been audited and adjusted
- Release branch has been created
- Originating branch has the version information updated to the new version
Build a release candidate
The core of the release process is the build-vote-fix cycle. Each cycle produces one release candidate. The Release Manager repeats this cycle until the community approves one release candidate, which is then finalized.
Build and stage Java artifacts with Maven
Set up a few environment variables to simplify Maven commands that follow. This identifies the release candidate being built. Start with RC_NUM
equal to 1
and increment it for each candidate.
RC_NUM="1"
TAG="v${VERSION}-RC${RC_NUM}"
Use Maven release plugin to build the release artifacts, as follows:
mvn release:prepare \
-Dresume=false \
-DreleaseVersion=${VERSION} \
-Dtag=${TAG} \
-DupdateWorkingCopyVersions=false
Use Maven release plugin to stage these artifacts on the Apache Nexus repository, as follows:
mvn release:perform
Review all staged artifacts. They should contain all relevant parts for each module, including pom.xml
, jar, test jar, source, test source, javadoc, etc. Artifact names should follow the existing format in which artifact name mirrors directory structure, e.g., distributedlog-core
. Carefully review any new artifacts.
Close the staging repository on Apache Nexus. When prompted for a description, enter “Apache DistributedLog, version X, release candidate Y”.
Stage source release on dist.apache.org
Copy the source release to the dev repository of dist.apache.org
.
-
If you have not already, check out the DistributedLog section of the
dev
repository ondist.apache.org
via Subversion. In a fresh directory:svn co https://dist.apache.org/repos/dist/dev/bookkeeper/distributedlog
-
Make a directory for the new release:
mkdir distributedlog/${VERSION}
-
Copy and rename the DistributedLog source distribution, hashes, and GPG signature:
cp ${DL_ROOT}/target/distributedlog-${VERSION}-src.tar.gz distributedlog/${VERSION}/distributedlog-${VERSION}-src.tar.gz cp ${DL_ROOT}/target/distributedlog-${VERSION}-src.tar.gz.asc distributedlog/${VERSION}/distributedlog-${VERSION}-src.tar.gz.asc cp ${DL_ROOT}/target/distributedlog-${VERSION}-src.tar.gz.md5 distributedlog/${VERSION}/distributedlog-${VERSION}-src.tar.gz.md5 cp ${DL_ROOT}/target/distributedlog-${VERSION}-src.tar.gz.sha1 distributedlog/${VERSION}/distributedlog-${VERSION}-src.tar.gz.sha1 cp ${DL_ROOT}/distributedlog-benchmark/target/distributedlog-benchmark-${VERSION}-bin.tar.gz distributedlog/${VERSION}/distributedlog-benchmark-${VERSION}-bin.tar.gz cp ${DL_ROOT}/distributedlog-benchmark/target/distributedlog-benchmark-${VERSION}-bin.tar.gz.asc distributedlog/${VERSION}/distributedlog-benchmark-${VERSION}-bin.tar.gz.asc cp ${DL_ROOT}/distributedlog-benchmark/target/distributedlog-benchmark-${VERSION}-bin.tar.gz.md5 distributedlog/${VERSION}/distributedlog-benchmark-${VERSION}-bin.tar.gz.md5 cp ${DL_ROOT}/distributedlog-benchmark/target/distributedlog-benchmark-${VERSION}-bin.tar.gz.sha1 distributedlog/${VERSION}/distributedlog-benchmark-${VERSION}-bin.tar.gz.sha1 cp ${DL_ROOT}/distributedlog-service/target/distributedlog-service-${VERSION}-bin.tar.gz distributedlog/${VERSION}/distributedlog-service-${VERSION}-bin.tar.gz cp ${DL_ROOT}/distributedlog-service/target/distributedlog-service-${VERSION}-bin.tar.gz.asc distributedlog/${VERSION}/distributedlog-service-${VERSION}-bin.tar.gz.asc cp ${DL_ROOT}/distributedlog-service/target/distributedlog-service-${VERSION}-bin.tar.gz.md5 distributedlog/${VERSION}/distributedlog-service-${VERSION}-bin.tar.gz.md5 cp ${DL_ROOT}/distributedlog-service/target/distributedlog-service-${VERSION}-bin.tar.gz.sha1 distributedlog/${VERSION}/distributedlog-service-${VERSION}-bin.tar.gz.sha1
-
Add and commit all the files.
svn add distributedlog/${VERSION} svn commit
-
Verify that files are present.
Build the API reference
DistributedLog publishes API reference manual for each release on the website. For Java SDK, that’s Javadoc.
Check out release candidate, as follows:
git checkout ${TAG}
Use Maven Javadoc plugin to generate the new Java reference manual, as follows:
mvn -DskipTests clean package javadoc:aggregate \
-Ddoctitle="Apache DistributedLog Library for Java, version ${VERSION}" \
-Dwindowtitle="Apache DistributedLog Library for Java, version ${VERSION}" \
-Dmaven.javadoc.failOnError=false
By default, the Javadoc will be generated in target/site/apidocs/
. Let ${JAVADOC_ROOT}
be the absolute path to apidocs
. (Pull request #1015 will hopefully simplify this process.)
Please carefully review the generated Javadoc. Check for completeness and presence of all relevant packages and package-info.java
; consider adding less relevant packages to the excludePackageNames
configuration. The index page is generated at ${JAVADOC_ROOT}/index.html
.
Checkout the asf-site
branch, as follows:
git checkout asf-site
Copy the generated javadoc files to the asf site, as follows:
mkdir -p content/docs/${VERSION}/api/java
cp -r target/site/apidocs/* content/docs/${VERSION}/api/java/
Propose a pull request for website updates
The final step of building the candidate is to propose a website pull request.
Follow the example pull request to make the modifications.
Finally, propose a pull request with these changes. (Don’t merge before finalizing the release.)
Checklist to proceed to the next step
- Maven artifacts deployed to the staging repository of repository.apache.org
- Source distribution deployed to the dev repository of dist.apache.org
- Website pull request proposed to list the release and publish the API reference manual
Vote on the release candidate
Once you have built and individually reviewed the release candidate, please share it for the community-wide review. Please review foundation-wide voting guidelines for more information.
Start the review-and-vote thread on the dev@ mailing list. Here’s an email template; please adjust as you see fit.
From: Release Manager
To<EMAIL_ADDRESS>Subject: [VOTE] Release 0.4.0, release candidate #0
Hi everyone,
Please review and vote on the release candidate #0 for the version 0.4.0, as follows:
[ ] +1, Approve the release
[ ] -1, Do not approve the release (please provide specific comments)
The complete staging area is available for your review, which includes:
* JIRA release notes [1],
* the official Apache source release to be deployed to dist.apache.org [2],
* all artifacts to be deployed to the Maven Central Repository [3],
* source code tag "v0.4.0-RC0" [4],
* website pull request listing the release and publishing the API reference manual [5].
The vote will be open for at least 72 hours. It is adopted by majority approval, with at least 3 PPMC affirmative votes.
Thanks,
Release Manager
[1] link
[2] link
[3] link
[4] link
[5] link
If there are any issues found in the release candidate, reply on the vote thread to cancel the vote. There’s no need to wait 72 hours. Proceed to the Fix Issues
step below and address the problem. However, some issues don’t require cancellation. For example, if an issue is found in the website pull request, just correct it on the spot and the vote can continue as-is.
If there are no issues, reply on the vote thread to close the voting. Then, tally the votes in a separate email. Here’s an email template; please adjust as you see fit.
From: Release Manager
To<EMAIL_ADDRESS>Subject: [RESULT] [VOTE] Release 0.4.0, release candidate #0
I'm happy to announce that we have unanimously approved this release.
There are XXX approving votes, XXX of which are binding:
* approver 1
* approver 2
* approver 3
* approver 4
There are no disapproving votes.
Thanks everyone!
Checklist to proceed to the finalization step
- Community votes to release the proposed candidate
Fix any issues
Any issues identified during the community review and vote should be fixed in this step.
Code changes should be proposed as standard pull requests to the master
branch and reviewed using the normal contributing process. Then, relevant changes should be cherry-picked into the release branch. The cherry-pick commits should then be proposed as the pull requests against the release branch, again reviewed and merged using the normal contributing process.
Once all issues have been resolved, you should go back and build a new release candidate with these changes.
Checklist to proceed to the next step
- Issues identified during vote have been resolved, with fixes committed to the release branch.
Finalize the release
Once the release candidate has been reviewed and approved by the community, the release should be finalized. This involves the final deployment of the release candidate to the release repositories, merging of the website changes, etc.
Deploy artifacts to Maven Central Repository
Use the Apache Nexus repository to release the staged binary artifacts to the Maven Central repository. In the Staging Repositories
section, find the relevant release candidate orgapachedistributedlog-XXX
entry and click Release
. Drop all other release candidates that are not being released.
Deploy source release to dist.apache.org
Copy the source release from the dev
repository to the release
repository at dist.apache.org
using Subversion.
Git tag
Create a new Git tag for the released version by copying the tag for the final release candidate, as follows:
git tag -s “v${VERSION}” ${TAG}
Merge website pull request
Merge the website pull request to list the release and publish the API reference manual created earlier.
Mark the version as released in JIRA
In JIRA, inside version management, hover over the current release and a settings menu will appear. Click Release
, and select today’s date.
Checklist to proceed to the next step
- Maven artifacts released and indexed in the Maven Central Repository
- Source distribution available in the release repository of dist.apache.org
- Website pull request to list the release and publish the API reference manual merged
- Release tagged in the source code repository
- Release version finalized in JIRA
Promote the release
Once the release has been finalized, the last step of the process is to promote the release within the project and beyond.
Apache mailing lists
Announce on the dev@ mailing list that the release has been finished.
Announce on the release on the user@ mailing list, listing major improvements and contributions.
ASF press release
Use reporter.apache.org to promote the release.
DistributedLog blog
Major or otherwise important releases should have a blog post. Write one if needed for this particular release. Minor releases that don’t introduce new major functionality don’t necessarily need to be blogged.
Social media
Tweet, post on Facebook, LinkedIn, and other platforms. Ask other contributors to do the same.
Checklist to declare the process completed
- Release announced on the user@ mailing list.
- Blog post published, if applicable.
- Apache Software Foundation press release published.
- Release announced on social media.
- Completion declared on the dev@ mailing list.
Improve the process
It is important that we improve the release processes over time. Once you’ve finished the release, please take a step back and look what areas of this process and be improved. Perhaps some part of the process can be simplified. Perhaps parts of this guide can be clarified.
If we have specific ideas, please start a discussion on the dev@ mailing list and/or propose a pull request to update this guide. Thanks!


(Route : Settings Menu, Customise Command)
This tab page allows you to set which colours are used in the Ameol display.
This is a Hot Spot image. Move your mouse pointer over the image
and when the mouse pointer changes to the shape of a hand click
the left mouse button once for extra help.
To change the colours for the terminal window displayed during blinking, press Alt Enter when the terminal window has the focus.


{% extends 'houdini_admin/base.html' %} {% block content %}
This is a page where a specific permission is required.
If you're here, that means you're logged in and have that permission!


new Celsius(config) Celsius function makes all requests to Wallet API. Parameters: Name Type Description config object Config has partner key, auth method and user secret. Source: core.js, line 41


'Dangerous' - How the opposition viewed Birmingham City's draw with Huddersfield
Latest Birmingham City news | Blues had to settle for a point in their Sky Bet Championship clash against the Terriers
by Mark WakefieldBirmingham City returned to Sky Bet Championship action on Saturday as they were held to a 1-1 draw with Huddersfield Town.
Fraizer Campbell opened the scoring for the Terriers before Marc Roberts equalised for Blues to earn a point from their trip to the John Smith’s Stadium.
Blues now lie in 15th place in the Championship table going into Wednesday night’s trip to face Sheffield Wednesday at Hillsborough.
We at Birmingham Live extensively covered Blues’ stalemate with the Terriers, but what about the opposition camp?
Here is how the opposition covered Saturday’s match.
MATCH REPORT – CLUB WEBSITE
Huddersfield Town returned to Sky Bet Championship action following the November international break with a 1-1 draw against Birmingham City.
Fraizer Campbell had put Town ahead 10 minutes into the second-half but a late Marc Roberts equaliser ensured that the points were shared at the John Smith’s Stadium.
Alex Pritchard made his first start under the Cowleys as one of four changes to the starting XI that lost at Preston a fortnight ago.
Jon Gorenc Stanković, Jonathan Hogg and Fraizer Campbell also came into the side alongside Pritch, who was making his 200th career appearance in all competitions.
The visitors switched the sides around at kick-off, so Town were attacking the Fantastic Media Stand in the first-half. It didn’t disrupt the Terriers rhythm early on however, as they worked the first real opportunity of the game when Elias Kachunga fired over after intercepting a loose Birmingham pass.
Both sides continued to battle in the opening exchanges of the first-half before the Blues created their first real chance of the game, as Jude Bellingham manoeuvred his way into the box before firing a strike over whilst off balance.
That opportunity seemed to be the spark the game needed, as Town immediately drove down the other end to create the game’s closest chance yet. Karlan Grant’s fizzed ball across the box found the run of Alex Pritchard who saw his goal-bound effort blocked on the slide.
Town nearly went one better on 36 minutes however, as Juninho Bacuna’s teasing cross found the unmarked Elias Kachunga in the box who produced a stunning save from Birmingham ‘keeper Connall Trueman at point blank range, before Marc Roberts blocked Fraizer Campbell’s rebound.
Bacca was one of five of Town’s First Team players that went away with their national sides over the break, having featured for Curaçao, but he continued to looked fresh at both ends of the pitch.
Birmingham City latest
This is your round up of all things Birmingham City; the one-stop shop that will keep you updated on the latest goings on at the club and beyond.
Transfers, injuries, match-days and managers, we’ve got you covered.
We’ll be bringing the very latest on the Blues throughout the week and around the clock.
Make sure you keep yourself updated with our handy daily catch up...
Must reads...
- 'My blood is boiling' - Former Birmingham City player accused of making vile slur
- Birmingham City's rampant starlets rated
- Pep Clotet explains that Birmingham City call - and who impressed him at Huddersfield
- Birmingham City player ratings as Jefferson Montero makes an impact at Huddersfield
- Garry Monk makes Birmingham City claim after Sheffield Wednesday charge
For all your latest BCFC news, opinion, analysis and transfer gossip, click here
You can follow our Blues reporter Brian Dick on Twitter, and his email address is<EMAIL_ADDRESS>Moments after his cross nearly broke the deadlock, a vital header at the back post kept the score at 0-0 on the stroke of half-time.
The clearance allowed Town to break on the counter and force a foul, but despite Alex Pritchard’s low-driven free-kick stinging the hands of the Birmingham ‘keeper, the two sides went into the break level at the John Smith’s Stadium.
Town continued to press for the opener straight after the half time and had their reward 10 minutes after the interval. An inch-perfect ball from Trevoh Chalobah found the run of Fraizer Campbell, with the striker maintaining his composure on the run to slot the ball past the ‘keeper and give Town the lead.
The Terriers continued to assert their dominance on the encounter and nearly had a second soon after. Elias Kachunga found himself unmarked inside the box once again but couldn’t divert Alex Pritchard’s cross from the left past the goalkeeper.
For all of Town’s efforts, the Blues drew level on 78 minutes. A well-worked free-kick was nodded in by Marc Roberts amongst a melee of players inside the box.
Danny Cowley’s side pushed forward in search of a winner in the final 10 minutes but couldn’t create any clear-cut chances to win the game, with the visitors holding firm to ensure that they would take a point from their trip to West Yorkshire.
Next up for Town is the second of two Sky Bet Championship home games in the space of four days with Swansea City the visitors to the John Smith’s Stadium on Tuesday 26 November 2019; 7.45pm kick-off.
PLAYER RATINGS – HUDDERSFIELD EXAMINER
Kamil Grabara 6
Did his calling and collecting work well and commanded the box soundly. Made a great late block to keep Town level.
Juninho Bacuna 6
Slotted in at right-back after deputising there for injured Danny Simpson at Preston. Made a great clearing header.
Jon Gorenc Stankovic 6
Making a first league start of the season and, barring an odd blip, did well alongside Schindler.
Christopher Schindler 7
Excellent covering work and tackling and always seemed to be in the right position.
Lewis O'Brien 6
Played at left-back in a formational re-jig to 4-2-3-1. Still managed to push forward with promise at times.
Trevoh Chalobah 7
Some promising early breaks. Played the pass of the game to set up Campbell's goal.
Jonathan Hogg 6
Back after a one-match ban and booked inside 10 minutes. Fought hard throughout.
Elias Kachunga 6
Made some promising first-half runs and worked hard. Unlucky not to score with a 35th-mintue header.
Alex Pritchard 7
Played some lovely passes and caused Birmingham plenty of problems. Close with a long-range free-kick.
Karlan Grant 6
Dangerous raiding from the left and put in a couple of very decent crosses. Had one shot saved.
Fraizer Campbell 8
Very lively and determined on his return to the side. Great run and finish for the goal - richly deserved.
DANNY COWLEY’S VERDICT
“I’m disappointed for the players really because I thought they put a lot into it. The resilience, the determination and the fight were really good,” said Danny.
“Proud of the players’ application. Proud of the players’ effort. We’ve got boys playing out of position, we had Lewis (O’Brien) playing left-back, Juninho (Bacuna) at right-back; I thought those two did great.
“We have to go back, and we have to work again. But I can rest easy tonight knowing the players fought really hard for one another in what was really difficult circumstances.”
“It was a brilliant pass, a pass good enough to win any football match and a great finish for Fraizer. It was a really well-worked goal.
“We’re disappointed today because we gave very little chances away, except for one soft one in the 80th minute, yet we created quite a lot of good chances today.
“It wasn’t going to be perfect with so much going against us in the week, so the fact we had all those qualities leaves me pleased about that.
“I’ve been a manager 13 years, near on 800 games, and that’s definitely the most difficult team I’ve had to select. It’s not straight-forward at the moment, we’ve got an unbalanced squad.
“We spoke to Lewis in Dubai and we’ve done a lot of work with him this week. Lewis will play anywhere for the team and do his very best.
“We watched Bacca’s games, we watch him against Wolves last year and the next game against Brighton. Fair play to Juninho because he’d been doing very well in centre midfield but when we spoke to him, he was willing to put the team first. We were proud of both of them today.”


Disk Class Reference
Defines a physical disk I/O device.
More...
#include <disk.h>
List of all members.
Detailed Description
Defines a physical disk I/O device.
The disk has a single surface, split up into "tracks", and each track split up into "sectors" (the same number of sectors on each track, and each sector has the same number of bytes of storage).
Addressing is by sector number -- each sector on the disk is given a unique number: track * SectorsPerTrack + offset within a track.
As with other I/O devices, the physical disk is an asynchronous device -- requests to read or write portions of the disk return immediately, and an interrupt is invoked later to signal that the operation completed.
The physical disk is in fact simulated via operations on a UNIX file.
To make life a little more realistic, the simulated time for each operation reflects a "track buffer" -- RAM to store the contents of the current track as the disk head passes by. The idea is that the disk always transfers to the track buffer, in case that data is requested later on. This has the benefit of eliminating the need for "skip-sector" scheduling -- a read request which comes in shortly after the head has passed the beginning of the sector can be satisfied more quickly, because its contents are in the track buffer. Most disks these days now come with a track buffer.
The track buffer simulation can be disabled by compiling with -DNOTRACKBUF
Constructor & Destructor Documentation
|
|
Create a simulated disk. Invoke (*callWhenDone)(callArg) every time a request completes. |
Member Function Documentation
| int Disk::ComputeLatency |
( |
int |
newSector, |
|
|
bool |
writing |
|
) |
|
|
|
|
Return how long a request to newSector will take: (seek + rotational delay + transfer) |
| void Disk::HandleInterrupt |
( |
|
) |
|
|
|
|
Interrupt handler, invoked when disk request finishes. |
| int Disk::ModuloDiff |
( |
int |
to, |
|
|
Time |
from |
|
) |
[private] |
|
|
|
Return number of sectors of rotational delay between target sector "to" and current sector position "from" |
| void Disk::ReadRequest |
( |
int |
sectorNumber, |
|
|
char * |
data |
|
) |
|
|
|
|
Read/write an single disk sector. These routines send a request to the disk and return immediately. Only one request allowed at a time! |
| int Disk::TimeToSeek |
( |
int |
newSector, |
|
|
int * |
rotation |
|
) |
[private] |
|
|
|
Returns how long it will take to position the disk head over the correct track on the disk. Since when we finish seeking, we are likely to be in the middle of a sector that is rotating past the head, we also return how long until the head is at the next sector boundary.
Disk seeks at one track per SEEK_TIME nanos (cf. stats.h) and rotates at one sector per ROTATION_TIME nanos |
| void Disk::UpdateLast |
( |
int |
newSector |
) |
[private] |
|
|
|
Keep track of the most recently requested sector. So we can know what is in the track buffer. - Parameters:
-
| newSector | accessed sector |
|
| void Disk::WriteRequest |
( |
int |
sectorNumber, |
|
|
char * |
data |
|
) |
|
|
|
|
Simulate a request to write a single disk sector Do the write immediately to the UNIX file Set up an interrupt handler to be called later, that will notify the caller when the simulator says the operation has completed.
Note that a disk only allows an entire sector to be written, not part of a sector.
- Parameters:
-
| sectorNumber | the disk sector to write |
| data | the bytes to be written |
|
Member Data Documentation
|
|
Is a disk operation in progress?
|
|
|
When the track buffer started being loaded |
|
|
UNIX file number for simulated disk.
|
|
|
Interrupt handler, to be invoked when any disk request finishes |
|
|
Argument to interrupt handler.
|
|
|
The previous disk request.
|
The documentation for this class was generated from the following files:
Generated on Mon Oct 17 19:44:18 2005 for Nachos by
1.4.4