class Mocha::Expectation
Methods on expectations returned from {Mock#expects}, {Mock#stubs}, {ObjectMethods#expects} and {ObjectMethods#stubs}.
Attributes
@private
Public Class Methods
@private
# File lib/mocha/expectation.rb, line 503 def initialize(mock, expected_method_name, backtrace = nil) @mock = mock @method_matcher = MethodMatcher.new(expected_method_name.to_sym) @parameters_matcher = ParametersMatcher.new @ordering_constraints = [] @side_effects = [] @cardinality, @invocation_count = Cardinality.exactly(1), 0 @return_values = ReturnValues.new @yield_parameters = YieldParameters.new @backtrace = backtrace || caller end
Public Instance Methods
@private
# File lib/mocha/expectation.rb, line 521 def add_in_sequence_ordering_constraint(sequence) sequence.constrain_as_next_in_sequence(self) end
@private
# File lib/mocha/expectation.rb, line 516 def add_ordering_constraint(ordering_constraint) @ordering_constraints << ordering_constraint end
@private
# File lib/mocha/expectation.rb, line 526 def add_side_effect(side_effect) @side_effects << side_effect end
Modifies expectation so that the expected method must be called at least a
minimum_number_of_times
.
@param [Integer] minimum_number_of_times minimum number of expected invocations. @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Expected method must be called at least twice.
object = mock() object.expects(:expected_method).at_least(2) 3.times { object.expected_method } # => verify succeeds object = mock() object.expects(:expected_method).at_least(2) object.expected_method # => verify fails
# File lib/mocha/expectation.rb, line 132 def at_least(minimum_number_of_times) @cardinality = Cardinality.at_least(minimum_number_of_times) self end
Modifies expectation so that the expected method must be called at least once.
@return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Expected method must be called at least once.
object = mock() object.expects(:expected_method).at_least_once object.expected_method # => verify succeeds object = mock() object.expects(:expected_method).at_least_once # => verify fails
# File lib/mocha/expectation.rb, line 150 def at_least_once at_least(1) self end
Modifies expectation so that the expected method must be called at most a
maximum_number_of_times
.
@param [Integer] maximum_number_of_times maximum number of expected invocations. @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Expected method must be called at most twice.
object = mock() object.expects(:expected_method).at_most(2) 2.times { object.expected_method } # => verify succeeds object = mock() object.expects(:expected_method).at_most(2) 3.times { object.expected_method } # => unexpected invocation
# File lib/mocha/expectation.rb, line 169 def at_most(maximum_number_of_times) @cardinality = Cardinality.at_most(maximum_number_of_times) self end
Modifies expectation so that the expected method must be called at most once.
@return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Expected method must be called at most once.
object = mock() object.expects(:expected_method).at_most_once object.expected_method # => verify succeeds object = mock() object.expects(:expected_method).at_most_once 2.times { object.expected_method } # => unexpected invocation
# File lib/mocha/expectation.rb, line 187 def at_most_once() at_most(1) self end
@private
# File lib/mocha/expectation.rb, line 536 def in_correct_order? @ordering_constraints.all? { |ordering_constraint| ordering_constraint.allows_invocation_now? } end
Constrains the expectation so that it must be invoked at the current point
in the sequence
.
To expect a sequence of invocations, write the expectations in order and add the +in_sequence(sequence)+ clause to each one.
Expectations in a sequence
can have any invocation count.
If an expectation in a sequence is stubbed, rather than expected, it can be
skipped in the sequence
.
An expected method can appear in multiple sequences.
@param [*Array<Sequence>] sequences sequences in which expected method should appear. @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@see Mocha::API#sequence
@example Ensure methods are invoked in a specified order.
breakfast = sequence('breakfast') egg = mock('egg') egg.expects(:crack).in_sequence(breakfast) egg.expects(:fry).in_sequence(breakfast) egg.expects(:eat).in_sequence(breakfast)
# File lib/mocha/expectation.rb, line 494 def in_sequence(*sequences) sequences.each { |sequence| add_in_sequence_ordering_constraint(sequence) } self end
@private
# File lib/mocha/expectation.rb, line 584 def inspect address = __id__ * 2 address += 0x100000000 if address < 0 "#<Expectation:0x#{'%x' % address} #{mocha_inspect} >" end
@private
# File lib/mocha/expectation.rb, line 551 def invocations_allowed? @cardinality.invocations_allowed?(@invocation_count) end
@private
# File lib/mocha/expectation.rb, line 561 def invoke @invocation_count += 1 perform_side_effects() if block_given? then @yield_parameters.next_invocation.each do |yield_parameters| yield(*yield_parameters) end end @return_values.next end
@private
# File lib/mocha/expectation.rb, line 546 def match?(actual_method_name, *actual_parameters) @method_matcher.match?(actual_method_name) && @parameters_matcher.match?(actual_parameters) && in_correct_order? end
@private
# File lib/mocha/expectation.rb, line 541 def matches_method?(method_name) @method_matcher.match?(method_name) end
@private
# File lib/mocha/expectation.rb, line 606 def method_signature "#{@mock.mocha_inspect}.#{<EMAIL_ADDRESS>end
@private
# File lib/mocha/expectation.rb, line 591 def mocha_inspect message =<EMAIL_ADDRESS>" message << case @invocation_count when 0 then "not yet invoked" when 1 then "invoked once" when 2 then "invoked twice" else "invoked #{@invocation_count} times" end message << ": " message << method_signature message << "<EMAIL_ADDRESS>{ |oc| oc.mocha_inspect }.join("; ")}" unless @ordering_constraints.empty? message end
Modifies expectation so that when the expected method is called, it yields
multiple times per invocation with the specified
parameter_groups
.
@param [*Array<Array>] parameter_groups each element of
parameter_groups
should iself be an Array
representing the parameters to be passed to the block for a single yield.
@return [Expectation] the same expectation, thereby allowing invocations of
other {Expectation} methods to be chained. @see then
@example When the expected_method
is called, the stub will
invoke the block twice, the first time it passes +'result_1'+,
+'result_2'+ as the parameters, and the second time it passes
'result_3' as the parameters.
object = mock() object.expects(:expected_method).multiple_yields(['result_1', 'result_2'], ['result_3']) yielded_values = [] object.expected_method { |*values| yielded_values << values } yielded_values # => [['result_1', 'result_2'], ['result_3]]
@example Yield different groups of parameters on different invocations of the expected method.
object = mock() object.stubs(:expected_method).multiple_yields([1, 2], [3]).then.multiple_yields([4], [5, 6]) yielded_values_from_first_invocation = [] yielded_values_from_second_invocation = [] object.expected_method { |*values| yielded_values_from_first_invocation << values } # first invocation object.expected_method { |*values| yielded_values_from_second_invocation << values } # second invocation yielded_values_from_first_invocation # => [[1, 2], [3]] yielded_values_from_second_invocation # => [[4], [5, 6]]
# File lib/mocha/expectation.rb, line 279 def multiple_yields(*parameter_groups) @yield_parameters.multiple_add(*parameter_groups) self end
Modifies expectation so that the expected method must never be called.
@return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Expected method must never be called.
object = mock() object.expects(:expected_method).never object.expected_method # => unexpected invocation object = mock() object.expects(:expected_method).never # => verify succeeds
# File lib/mocha/expectation.rb, line 112 def never @cardinality = Cardinality.exactly(0) self end
Modifies expectation so that the expected method must be called exactly once.
Note that this is the default behaviour for an expectation, but you may wish to use it for clarity/emphasis.
@return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Expected method must be invoked exactly once.
object = mock() object.expects(:expected_method).once object.expected_method # => verify succeeds object = mock() object.expects(:expected_method).once object.expected_method object.expected_method # => unexpected invocation object = mock() object.expects(:expected_method).once # => verify fails
# File lib/mocha/expectation.rb, line 95 def once @cardinality = Cardinality.exactly(1) self end
@private
# File lib/mocha/expectation.rb, line 531 def perform_side_effects @side_effects.each { |side_effect| side_effect.perform } end
Modifies expectation so that when the expected method is called, it raises
the specified exception
with the specified
message
i.e. calls +Kernel#raise(exception, message)+.
@param [Class,Exception,String,#exception] exception exception to be raised or message to be passed to RuntimeError. @param [String] message exception message. @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@see Kernel#raise @see then
@overload def raises @overload def raises(exception) @overload def raises(exception, message)
@example Raise specified exception if expected method is invoked.
object = stub() object.stubs(:expected_method).raises(Exception, 'message') object.expected_method # => raises exception of class Exception and with message 'message'
@example Raise custom exception with extra constructor parameters by passing in an instance of the exception.
object = stub() object.stubs(:expected_method).raises(MyException.new('message', 1, 2, 3)) object.expected_method # => raises the specified instance of MyException
@example Raise different exceptions on consecutive invocations of the expected method.
object = stub() object.stubs(:expected_method).raises(Exception1).then.raises(Exception2) object.expected_method # => raises exception of class Exception1 object.expected_method # => raises exception of class Exception2
@example Raise an exception on first invocation of expected method and then return values on subsequent invocations.
object = stub() object.stubs(:expected_method).raises(Exception).then.returns(2, 3) object.expected_method # => raises exception of class Exception1 object.expected_method # => 2 object.expected_method # => 3
# File lib/mocha/expectation.rb, line 366 def raises(exception = RuntimeError, message = nil) @return_values += ReturnValues.new(ExceptionRaiser.new(exception, message)) self end
Modifies expectation so that when the expected method is called, it returns
the specified value
.
@return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. @see then
@overload def returns(value)
@param [Object] value value to return on invocation of expected method.
@overload def returns(*values)
@param [*Array] values values to return on consecutive invocations of expected method.
@example Return the same value on every invocation.
object = mock() object.stubs(:stubbed_method).returns('result') object.stubbed_method # => 'result' object.stubbed_method # => 'result'
@example Return a different value on consecutive invocations.
object = mock() object.stubs(:stubbed_method).returns(1, 2) object.stubbed_method # => 1 object.stubbed_method # => 2
@example Alternative way to return a different value on consecutive invocations.
object = mock() object.stubs(:expected_method).returns(1, 2).then.returns(3) object.expected_method # => 1 object.expected_method # => 2 object.expected_method # => 3
@example May be called in conjunction with {#raises} on the same expectation.
object = mock() object.stubs(:expected_method).returns(1, 2).then.raises(Exception) object.expected_method # => 1 object.expected_method # => 2 object.expected_method # => raises exception of class Exception1
@example Note that in Ruby a method returning multiple values is exactly
equivalent to a method returning an Array
of those values.
object = mock() object.stubs(:expected_method).returns([1, 2]) x, y = object.expected_method x # => 1 y # => 2
# File lib/mocha/expectation.rb, line 326 def returns(*values) @return_values += ReturnValues.build(*values) self end
@private
# File lib/mocha/expectation.rb, line 556 def satisfied? @cardinality.satisfied?(@invocation_count) end
@overload def then
Used as syntactic sugar to improve readability. It has no effect on state of the expectation.
@overload def then(state_machine.is(state_name))
Used to change the +state_machine+ to the state specified by +state_name+ when the expected invocation occurs. @param [StateMachine::State] state_machine.is(state_name) provides a mechanism to change the +state_machine+ into the state specified by +state_name+ when the expected method is invoked. @see API#states @see StateMachine @see #when
@return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Using {#then} as syntactic sugar when specifying values to be returned and exceptions to be raised on consecutive invocations of the expected method.
object = mock() object.stubs(:expected_method).returns(1, 2).then.raises(Exception).then.returns(4) object.expected_method # => 1 object.expected_method # => 2 object.expected_method # => raises exception of class Exception object.expected_method # => 4
@example Using {#then} to change the state
of a
state_machine
on the invocation of an expected method.
power = states('power').starts_as('off') radio = mock('radio') radio.expects(:switch_on).then(power.is('on')) radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on')) radio.expects(:adjust_volume).with(+5).when(power.is('on')) radio.expects(:select_channel).with('BBC World Service').when(power.is('on')) radio.expects(:adjust_volume).with(-5).when(power.is('on')) radio.expects(:switch_off).then(power.is('off'))
# File lib/mocha/expectation.rb, line 440 def then(*parameters) if parameters.length == 1 state = parameters.first add_side_effect(ChangeStateSideEffect.new(state)) end self end
Modifies expectation so that when the expected method is called, it throws
the specified tag
with the specific return value
object
i.e. calls +Kernel#throw(tag, object)+.
@param [Symbol,String] tag tag to throw to transfer control to the active catch block. @param [Object] object return value for the catch block. @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@see Kernel#throw @see then
@overload def throw(tag) @overload def throw(tag, object)
@example Throw tag when expected method is invoked.
object = stub() object.stubs(:expected_method).throws(:done) object.expected_method # => throws tag :done
@example Throw tag with return value object
c.f.
+Kernel#throw+.
object = stub() object.stubs(:expected_method).throws(:done, 'result') object.expected_method # => throws tag :done and causes catch block to return 'result'
@example Throw different tags on consecutive invocations of the expected method.
object = stub() object.stubs(:expected_method).throws(:done).then.throws(:continue) object.expected_method # => throws :done object.expected_method # => throws :continue
@example Throw tag on first invocation of expected method and then return values for subsequent invocations.
object = stub() object.stubs(:expected_method).throws(:done).then.returns(2, 3) object.expected_method # => throws :done object.expected_method # => 2 object.expected_method # => 3
# File lib/mocha/expectation.rb, line 405 def throws(tag, object = nil) @return_values += ReturnValues.new(Thrower.new(tag, object)) self end
Modifies expectation so that the number of calls to the expected method
must be within a specific range
.
@param [Range,Integer] range specifies the allowable range in the number of expected invocations. @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Specifying a specific number of expected invocations.
object = mock() object.expects(:expected_method).times(3) 3.times { object.expected_method } # => verify succeeds object = mock() object.expects(:expected_method).times(3) 2.times { object.expected_method } # => verify fails
@example Specifying a range in the number of expected invocations.
object = mock() object.expects(:expected_method).times(2..4) 3.times { object.expected_method } # => verify succeeds object = mock() object.expects(:expected_method).times(2..4) object.expected_method # => verify fails
# File lib/mocha/expectation.rb, line 44 def times(range) @cardinality = Cardinality.times(range) self end
Modifies expectation so that the expected method must be called exactly twice.
@return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained.
@example Expected method must be invoked exactly twice.
object = mock() object.expects(:expected_method).twice object.expected_method object.expected_method # => verify succeeds object = mock() object.expects(:expected_method).twice object.expected_method object.expected_method object.expected_method # => unexpected invocation object = mock() object.expects(:expected_method).twice object.expected_method # => verify fails
# File lib/mocha/expectation.rb, line 70 def twice @cardinality = Cardinality.exactly(2) self end
@private
# File lib/mocha/expectation.rb, line 579 def used? @cardinality.used?(@invocation_count) end
@private
# File lib/mocha/expectation.rb, line 573 def verified?(assertion_counter = nil) assertion_counter.increment if assertion_counter && @cardinality.needs_verifying? @cardinality.verified?(@invocation_count) end
Constrains the expectation to occur only when the
state_machine
is in the state specified by
state_name
.
@param [StateMachine::StatePredicate] state_machine.is(state_name) provides
a mechanism to determine whether the state_machine
is in the
state specified by state_name
when the expected method is
invoked. @return [Expectation] the same expectation, thereby allowing
invocations of other {Expectation} methods to be chained.
@see Mocha::API#states @see StateMachine @see then
@example Using {#when} to only allow invocation of methods when “power” state machine is in the “on” state.
power = states('power').starts_as('off') radio = mock('radio') radio.expects(:switch_on).then(power.is('on')) radio.expects(:select_channel).with('BBC Radio 4').when(power.is('on')) radio.expects(:adjust_volume).with(+5).when(power.is('on')) radio.expects(:select_channel).with('BBC World Service').when(power.is('on')) radio.expects(:adjust_volume).with(-5).when(power.is('on')) radio.expects(:switch_off).then(power.is('off'))
# File lib/mocha/expectation.rb, line 467 def when(state_predicate) add_ordering_constraint(InStateOrderingConstraint.new(state_predicate)) self end
Modifies expectation so that the expected method must be called with
expected_parameters
.
May be used with parameter matchers in {ParameterMatchers}.
@param [*Array] expected_parameters parameters expected. @yield optional
block specifying custom matching. @yieldparam [*Array] actual_parameters
parameters with which expected method was invoked. @yieldreturn [Boolean]
true
if actual_parameters
are acceptable. @return
[Expectation] the same expectation, thereby allowing invocations of other
{Expectation} methods to be chained.
@example Expected method must be called with expected parameters.
object = mock() object.expects(:expected_method).with(:param1, :param2) object.expected_method(:param1, :param2) # => verify succeeds object = mock() object.expects(:expected_method).with(:param1, :param2) object.expected_method(:param3) # => verify fails
@example Expected method must be called with a value divisible by 4.
object = mock() object.expects(:expected_method).with() { |value| value % 4 == 0 } object.expected_method(16) # => verify succeeds object = mock() object.expects(:expected_method).with() { |value| value % 4 == 0 } object.expected_method(17) # => verify fails
# File lib/mocha/expectation.rb, line 223 def with(*expected_parameters, &matching_block) @parameters_matcher = ParametersMatcher.new(expected_parameters, &matching_block) self end
Modifies expectation so that when the expected method is called, it yields
with the specified parameters
.
May be called multiple times on the same expectation for consecutive invocations.
@param [*Array] parameters parameters to be yielded. @return [Expectation] the same expectation, thereby allowing invocations of other {Expectation} methods to be chained. @see then
@example Yield parameters when expected method is invoked.
object = mock() object.expects(:expected_method).yields('result') yielded_value = nil object.expected_method { |value| yielded_value = value } yielded_value # => 'result'
@example Yield different parameters on different invocations of the expected method.
object = mock() object.stubs(:expected_method).yields(1).then.yields(2) yielded_values_from_first_invocation = [] yielded_values_from_second_invocation = [] object.expected_method { |value| yielded_values_from_first_invocation << value } # first invocation object.expected_method { |value| yielded_values_from_second_invocation << value } # second invocation yielded_values_from_first_invocation # => [1] yielded_values_from_second_invocation # => [2]
# File lib/mocha/expectation.rb, line 252 def yields(*parameters) @yield_parameters.add(*parameters) self end


Demo hotels
Running the project
The project have got the Maven structure, so you can call from command line:
- download project from Source Forge
- unzip sources to a new directory and go there
- run server: mvn jetty:run
- and open application: firefox localhost:8080
The Java 6.0+ is required for complilaction the souces.
How to open this project?
Use a one of the preferred tools to open the project:
The Application License
Copyright 2013-2015 Pavel Ponec<EMAIL_ADDRESS>Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Third-party licenses
There is a list of used library licenses and data resources.
Ujorm
Apache Wicket
Spring Framework
H2 Database Engine
H2 is dual licensed and available under a modified version of the MPL 1.1 (
Mozilla Public License) or under the (unmodified) EPL 1.0 (
Eclipse Public License). The changes to the MPL are
underlined. There is a license FAQ for both the MPL and the EPL, most of that is applicable to the H2 license as well. ,
see the
original resource.
Logback
As of release 0.9.18, logback source code and binaries are dual-licensed under the EPL v1.0 and the LGPL 2.1,
see the
original resource.
Silk Icons
Bootstrap v2.3.2
Copyright 2012 Twitter, Inc
Licensed under the
Apache License v2.0
Designed and built with all the love in the world @twitter by @mdo and @fat.
Data License
Note
Written by Pavel Ponec<EMAIL_ADDRESS>on 2015-03-09


The action's unique identifier. If your plugin supports multiple actions, you should use this value to see which action was triggered.
Sets the action
The coordinates column of the action triggered.
Gets the column
The coordinates column of the action triggered.
Sets the column
An opaque value identifying the instance's action. You will need to pass this opaque value to several APIs like the setTitle API.
Gets the context
An opaque value identifying the instance's action. You will need to pass this opaque value to several APIs like the setTitle API.
Sets the context
An opaque value identifying the device.
Gets the device
An opaque value identifying the device.
Sets the device
Boolean indicating if the action is inside a Multi Action.
Gets the is in multi-action state
Boolean indicating if the action is inside a Multi Action.
Sets the is in multi-action state
The coordinates row of the action triggered.
Gets the row
The coordinates row of the action triggered.
Sets the row
Sets the settings
This is a parameter that is only set when the action has multiple states defined in its manifest.json. The 0-based value contains the current state of the action.
Gets the state
This is a parameter that is only set when the action has multiple states defined in its manifest.json. The 0-based value contains the current state of the action.
Sets the state
This is a parameter that is only set when the action is triggered with a specific value from a Multi Action. For example if the user sets the Game Capture Record action to be disabled in a Multi Action, you would see the value 1. Only the value 0 and 1 are valid.
Gets the user desired state
This is a parameter that is only set when the action is triggered with a specific value from a Multi Action. For example if the user sets the Game Capture Record action to be disabled in a Multi Action, you would see the value 1. Only the value 0 and 1 are valid.
Sets the user desired state
Disables automatic debounce
Disables automatic save
Enables automatic debounce
Enables automatic save
Gets the action
Gets the context
Gets the device
Gets context settings
your settings interface for autocomplete
Save context settings
for the debounce
Set context settings
your settings interface for autocomplete
for the debounce
Set single or multiple attributes for settings
for the debounce
Generated using TypeDoc
The action's unique identifier. If your plugin supports multiple actions, you should use this value to see which action was triggered.
Gets the action


Hi, my name is Stacey and welcome to my travel blog!
I am a graduate, with skills in CODING, JOURNALISM and MEDIA. I now have the chance to fufill my desire to travel the world and even to figure out who I am. I love exploring, experiencing different cultures and eating LOTS of food! If you like what you see so far, then join me on my journey.
Each week I shall be posting a new story filled with FREE travel tips, advice and short snapshots of all that I have experienced in each new place.
You can follow me on social media for more pics, and even share your own stories. Why not explore my blog to see the places I have visited so far?!


11.3 The Redirector Pool
A redirector can take an arbitrarily long
time to
return its answer. For example, it may need to make a database query,
search through long lists of regular expressions, or make some
complex computations. Squid uses a pool of redirector processes so
that they can all work in parallel. While one is busy, Squid hands a
new request off to another.
For each new request, Squid examines the pool of redirector processes
in order. It submits the request to the first idle process. If your
request rate is very low, the first redirector may be able to handle
all requests itself.
You can control the size of the redirector pool
with the
redirect_children directive. The default value
is five processes. Note that Squid doesn't
dynamically increase or decrease the size of the pool depending on
the load. Thus, it is a good idea to be a little liberal. If all
redirectors are busy, Squid queues pending requests. If the queue
becomes too large (bigger than twice the pool size), Squid exits with
a fatal error message:
FATAL: Too many queued redirector requests
In this case, you need to increase the size of the redirector pool or
change something so that the redirectors can process requests faster.
You can use the cache manager's
redirector page to find out if you have too few,
or too many redirectors running. For example:
% squidclient mgr:redirector
...
Redirector Statistics:
program: /usr/local/squid/bin/myredir
number running: 5 of 5
requests sent: 147
replies received: 142
queue length: 2
avg service time: 953.83 msec
# FD PID # Requests Flags Time Offset Request
1 10 35200 46 AB 0.902 0 http://...
2 11 35201 29 AB 0.401 0 http://...
3 12 35202 25 AB 1.009 1 cache_o...
4 14 35203 25 AB 0.555 0 http://...
5 15 35204 21 AB 0.222 0 http://...
If, as in this example, you see that the last redirector has almost
as many requests as the second to last, you should probably increase
the size of the redirector pool. If, on the other hand, you see many
redirectors with no requests, you can probably decrease the pool
size.
|


| What if it made perfect sense for ordinary people to kill each other for money? Better than slow grinding financial ruin and misery, and all done according to a strict code by consenting adults. This is Trading. | |
| Genres: | Thriller |
| Director: | Rachael Moriarty, Peter Murphy |
| Writer: | Rachael Moriarty, Peter Murphy |
Cast: | Harry Fox - Killian Scott Vernon Stynes - John Bradley Orla Johnson - Nika McGuigan Anthony Grogan - Peter O'Meara Ken - Barry Keoghan Big John - Tom Davis Nuala - Aoibhinn McGinnity Kevin - David Murray Vicious - Caoilfhionn Dunne Helen Stynes - Olwen Fouere Tallman - David McSavage Pickaxe - Donal O'Farrell Kicker - Dónall Ó Héalai Bri234 - Tom O'Sulleabhain Simon - Nick Lee Ger - Laurence Kinlan Tony - Patrick McDonnell Sally - Mary O'Driscoll Garden Centre Customer - Lydia McGuinness Baz - Barry Mullarkey Lionsmane - Martin Gaughan |


Mayhem
{^g}Skill Modifier{^n}{^w}Unleash thunderous destruction from ripping the ground apart.
${value} Electrical Burn Damage over ${duration} Second(s)
min: 180.0 Electrical Burn Damage over min: 3.0 Second(s)
+${value}% Physical Damage
-40
+${value}% Stun Duration
-300
MaxLevel
1
UltimateLevel
1


Listen to rare Prince track ‘Don’t Let Him Fool Ya’
It will feature on forthcoming '1999' reissue
Prince‘s estate has shared rare track ‘Don’t Let Him Fool Ya’ for the first time.
Recorded in 1982 at the late icon’s home studio on Kiowa Trail in Chanhassen, Minnesota, the track will appear on a new reissue of ‘1999’, which is out on November 29.
The track has been shared among fans for years but this is the first time it has officially been released. You can listen to it below.
The song is among 35 previously unreleased tracks on the forthcoming reissue.
Fans will be able to get their hands on a Super Deluxe Edition (comprised of 10 LPs and a DVD), a Deluxe Edition (2CD or 4LP 180g vinyl/download and streaming), or the standard remastered version (1CD or 2LP 180g Purple Vinyl/download and streaming).
The Super Deluxe Edition’s DVD is a full, previously unreleased concert film shot at Prince’s Houston Summit show in 1982. Also included in the top-tier package are 23 previously unissued studio tracks (recorded between November 1981 and January 1983), and a complete live audio performance of the ‘1999’ tour.
Unseen handwritten notes from the Purple One himself will feature in the collection alongside rare photos from Prince’s early ‘80s photographer, Allen Beaulieu.
Check out the full tracklist for Prince’s ‘1999’ reissue below.
CD One / LPs One and Two: Remastered Album
1. “1999”
2. “Little Red Corvette”
3. “Delirious”
4. “Let’s Pretend We’re Married”
5. “D.M.S.R.”
6. “Automatic”
7. “Something in the Water (Does Not Compute)”
8. “Free”
9. “Lady Cab Driver”
10. “All the Critics Love U in New York”
11. “International Lover”
CD Two / LPs Three and Four: Promo Mixes & B Sides
1. “1999” (7″ stereo edit)
2. “1999” (7″ mono promo-only edit)
3. “Free” (promo-only edit)
4. “How Come You Don’t Call Me Anymore” (“1999” b-side)
5. “Little Red Corvette” (7″ edit)
6. “All The Critics Love U In New York” (7” edit)
7. “Lady Cab Driver” (7″ edit)
8. “Little Red Corvette” (Dance Remix promo-only edit)
9. “Little Red Corvette” (Special Dance Mix)
10. “Delirious” (7″ edit)
11. “Horny Toad” (“Delirious” b-side)
12. “Automatic” (7″ edit)
13. “Automatic” (video version)
14. “Let’s Pretend We’re Married” (7″ edit)
15. “Let’s Pretend We’re Married” (7″ mono promo-only edit)
16. “Irresistible Bitch” (“Let’s Pretend We’re Married” b-side)
17. “Let’s Pretend We’re Married” (video version)
18. “D.M.S.R.” (edit)
CD Three / LPs Five and Six: Vault, Part 1
1. “Feel U Up”
2. “Irresistible Bitch”
3. “Money Don’t Grow on Trees”
4. “Vagina”
5. “Rearrange”
6. “Bold Generation”
7. “Colleen”
8. “International Lover” (Take 1, live in studio)
9. “Turn It Up”
10. “You’re All I Want”
11. “Something In The Water (Does Not Compute)” (Original Version)
12. “If It’ll Make U Happy”
13. “How Come U Don’t Call Me Anymore?” (Take 2, live in studio)
All tracks previously unreleased
CD Four / LPs Seven and Eight: Vault, Part 2
1. “Possessed” (1982 version)
2. “Delirious” (full length)
3. “Purple Music”
4. “Yah, You Know”
5. “Moonbeam Levels” **
6. “No Call U”
7. “Can’t Stop This Feeling I Got”
8. “Do Yourself a Favor”
9. “Don’t Let Him Fool Ya”
10. “Teacher, Teacher”
11. “Lady Cab Driver” / “I Wanna Be Your Lover” / “Head” / “Little Red Corvette” (tour demo)
All tracks previously unreleased except **, released on the 2016. compilation, 4Ever
CD Five / LPs Nine and Ten: Live in Detroit – November 30, 1982. (midnight show)
1. “Controversy”
2. “Let’s Work”
3. “Little Red Corvette”
4. “Do Me, Baby”
5. “Head”
6. “Uptown”
7. “Interlude”
8.
9. “Automatic”
10. “International Lover”
11. “1999”
12. “D.M.S.R.”
All tracks previously unreleased
DVD: Live In Houston – December 29, 1982 *
1. “Controversy”
2 “Let’s Work”
3. “Do Me, Baby”
4. “D.M.S.R.”
5. “Interlude” – piano improvisation (contains elements of “With You”)
6.
7. “Lady Cab Driver”
8. “Automatic”
9. “International Lover”
10. “1999”
11. “Head” (contains elements of “Sexuality”)
All tracks previously unreleased
Meanwhile, it was recently revealed that Prince hoped that his recent memoir The Beautiful Ones could “solve racism”, according to writer Dan Piepenbring.


portion adjusting member plate supporting tripod second head opening threaded receiving connecting shell locking upper claim hole CLAIM-TEXT:. claim-ref[claim connected defines sidewall away space surface pad substantially flange includes document-id:: end angle classification-national:: extends [patcit]: citation: cited communicating comprising examiner figref[FIG. plate. portion, position protrusion relative shape space, CLAIM-TEXT:a central comprises corresponding embodiment, fixedly holes outer (not EMI-D camera inner received recess [addressbook]: action-date: defining generating-office:: number opening, passes portion. present rotated shell, shooting surrounding


ArkavQuarium
For those who loves InsaniQuarium with low-spec PC
Here is a list of all file members with links to the files they belong to:
- b -
buyEggButtonXEnd :
Constants.hpp
buyEggButtonXStart :
Constants.hpp
buyEggButtonYEnd :
Constants.hpp
buyEggButtonYStart :
Constants.hpp
buyGuppyButtonXEnd :
Constants.hpp
buyGuppyButtonXStart :
Constants.hpp
buyGuppyButtonYEnd :
Constants.hpp
buyGuppyButtonYStart :
Constants.hpp
buyPiranhaButtonXEnd :
Constants.hpp
buyPiranhaButtonXStart :
Constants.hpp
buyPiranhaButtonYEnd :
Constants.hpp
buyPiranhaButtonYStart :
Constants.hpp
buySnailButtonXEnd :
Constants.hpp
buySnailButtonXStart :
Constants.hpp
buySnailButtonYEnd :
Constants.hpp
buySnailButtonYStart :
Constants.hpp
- c -
closed :
Constants.hpp
coinClickRadius :
Constants.hpp
coinDeletionInterval :
Constants.hpp
coinFadeProgressIncrementTime :
Constants.hpp
coinMoveSpeed :
Constants.hpp
coinProgressIncrementTime :
Constants.hpp
coinTextColorB :
Constants.hpp
coinTextColorG :
Constants.hpp
coinTextColorR :
Constants.hpp
coinTextSize :
Constants.hpp
coinTextX :
Constants.hpp
coinTextY :
Constants.hpp
- d -
deadLeft :
Constants.hpp
deadRight :
Constants.hpp
Direction :
Constants.hpp
- e -
eggCountTextColorB :
Constants.hpp
eggCountTextColorG :
Constants.hpp
eggCountTextColorR :
Constants.hpp
eggCountTextSize :
Constants.hpp
eggCountTextX :
Constants.hpp
eggCountTextY :
Constants.hpp
eggPrice :
Constants.hpp
eggPriceTextX :
Constants.hpp
eggPriceTextY :
Constants.hpp
- f -
fading :
Constants.hpp
fRand() :
Helper.hpp
,
Helper.cpp
- g -
gameFrameRate :
Constants.hpp
gameInitialCoin :
Constants.hpp
gameScreenBottomPadding :
Constants.hpp
gameScreenHeight :
Constants.hpp
gameScreenLeftPadding :
Constants.hpp
gameScreenRightPadding :
Constants.hpp
gameScreenTopPadding :
Constants.hpp
gameScreenWidth :
Constants.hpp
GameState :
Constants.hpp
guppyCoinInterval :
Constants.hpp
guppyCoinMultiplier :
Constants.hpp
guppyDeadProgressIncrementTime :
Constants.hpp
guppyEatRadius :
Constants.hpp
guppyFoodThres :
Constants.hpp
guppyFullInterval :
Constants.hpp
guppyHungerInterval :
Constants.hpp
guppyMoveProgressIncrementTime :
Constants.hpp
guppyMoveSpeed :
Constants.hpp
guppyPrice :
Constants.hpp
guppyPriceTextX :
Constants.hpp
guppyPriceTextY :
Constants.hpp
guppyTurnProgressIncrementTime :
Constants.hpp
- l -
left :
Constants.hpp
lose :
Constants.hpp
loseStartButtonXEnd :
Constants.hpp
loseStartButtonXStart :
Constants.hpp
loseStartButtonYEnd :
Constants.hpp
loseStartButtonYStart :
Constants.hpp
- m -
main() :
testaquarium.cpp
,
testcoin.cpp
,
testpiranha.cpp
,
testpellet.cpp
,
main.cpp
,
testsnail.cpp
,
driverlinkedlist.cpp
,
testguppy.cpp
mainStartButtonXEnd :
Constants.hpp
mainStartButtonXStart :
Constants.hpp
mainStartButtonYEnd :
Constants.hpp
mainStartButtonYStart :
Constants.hpp
maxLevel :
Constants.hpp
movingLeft :
Constants.hpp
movingRight :
Constants.hpp
- p -
pelletPrice :
Constants.hpp
pelletPriceTextX :
Constants.hpp
pelletPriceTextY :
Constants.hpp
pelletProgressIncrementTime :
Constants.hpp
pelletSpeed :
Constants.hpp
pi :
Constants.hpp
piranhaCoinInterval :
Constants.hpp
piranhaDeadProgressIncrementTime :
Constants.hpp
piranhaEatRadius :
Constants.hpp
piranhaFoodThres :
Constants.hpp
piranhaFullInterval :
Constants.hpp
piranhaHungerInterval :
Constants.hpp
piranhaMoveProgressIncrementTime :
Constants.hpp
piranhaMoveSpeed :
Constants.hpp
piranhaPrice :
Constants.hpp
piranhaPriceTextX :
Constants.hpp
piranhaPriceTextY :
Constants.hpp
piranhaTurnProgressIncrementTime :
Constants.hpp
priceTextColorB :
Constants.hpp
priceTextColorG :
Constants.hpp
priceTextColorR :
Constants.hpp
priceTextSize :
Constants.hpp
progressPeriod :
Constants.hpp
- r -
randomMoveInterval :
Constants.hpp
right :
Constants.hpp
- s -
snailEatRadius :
Constants.hpp
snailMoveProgressIncrementTime :
Constants.hpp
snailPrice :
Constants.hpp
snailPriceTextX :
Constants.hpp
snailPriceTextY :
Constants.hpp
snailSpeed :
Constants.hpp
snailTurnProgressIncrementTime :
Constants.hpp
State :
Constants.hpp
stillLeft :
Constants.hpp
stillRight :
Constants.hpp
- t -
turningLeft :
Constants.hpp
turningRight :
Constants.hpp
- w -
win :
Constants.hpp
winStartButtonXEnd :
Constants.hpp
winStartButtonXStart :
Constants.hpp
winStartButtonYEnd :
Constants.hpp
winStartButtonYStart :
Constants.hpp
Generated by
1.8.14


Squishy
He will scratch and bite his way to your heart.
Squishy
He will scratch and bite his way to your heart.
Squishy
He will scratch and bite his way to your heart.
Find out which cat best works for you!
He will scratch and bite his way to your heart.
He will scratch and bite his way to your heart.
He will scratch and bite his way to your heart.
He will scratch and bite his way to your heart.
He will scratch and bite his way to your heart.
He will scratch and bite his way to your heart.


FANTOM CAT
Assembly and Annotations
FANTOM CAT (CAGE Associated Transcriptome) is a human transcriptome meta-assembly based on association of CAGE (Cap Analysis of Gene Expression) data and transcript models from diverse sources. In FANTOM CAT, gene models are robustly supported by transcription initiation evidences and represents the most 5’completed human transcriptome to date. These genes are comprehensively annotated into categories based on their genomic and epigenomic features, including 27,919 high-confidence long non-coding RNA (lncRNA) genes.
Expression, Genome-Wide Associations and Functional Implications
In FANTOM CAT, every gene is linked to expression profiles from 1,829 diverse samples. Based on the expression profiles and genome-wide association studies, FANTOM CAT genes are defined to be associated with specific types of cell (as sample ontologies) and traits respectively. By intersecting their cell-type specificity and trait associations, we identified the genes that are associated with specific traits and expressed in the relevant cell-types, and these included 1,970 lncRNA genes.
Browse, View, Filter, Intersect and Download
This web application allows users to browse FANTOM CAT genes, view their genomic loci through ZENBU, filter by their annotations, intersect them with their associated sample ontologies or traits, and download the relevant data. Alternatively, users can also browse by trait or sample ontologies, and intersect with their associated genes. Click on the circles below and start browsing.


Select the folder which will act as the root folder of your server (The server will autometically start after you select the folder)


The Modest Maps library allows your Processing application to display tile-based
maps of the world. It is capable of displaying maps from services like
Yahoo Maps and Microsoft Virtual Earth but is recommended for use with custom maps.
@libname Modest Maps


Simulating An Epidemic
What would happen if everyone went about their lives like COVID-19 doesn't exist? How quickly would the disease spread? On the other hand, what if a significant proportion of the people in your area were tested every day for the disease? How quickly could it be eradicated? We all have that little scientist in our head, asking hypothetical questions about the current pandemic that has changed our lives forever.
This page contains a series of limited toy simulations for indulging said scientist, allowing them to alter many characteristics of the disease and of how people behave, to help understand why preventative measures such as quarantine, social distancing, community lock-downs, personal hygiene and extensive testing are important tools in this fight.
There are four main sections:
- Key Takeaways - There is some guidance here in what you can expect to observe, and the buttons restart any simulation with predetermined settings.
- Controls - Here you can change the many variables that can have drastic effects on the outcome of the simulation.
- Population Status Chart - This chart documents the distribution of people who are healthy, infected, recovered or dead at each point in time, at the end providing insight into how the disease progressed.
- Simulation - Here you can watch hundreds of people (small circles) move around their area as they interact with disease carriers and spread the disease themselves.
Key Takeaways
*Disclaimer* I am not an epidemiologist so any lessons learned here should not be generalized without deeper consideration. These simulations aren't meant to be realistic (people aren't little dots randomly roaming around a rectangle), but they allow us to explore ideas by being experimental and quantitative even if it’s in a necessarily limited fashion.
- While the disease still exists, as soon as people let up and go back to their normal lives with nothing in place to contain the cases, few though they might be, there will be an additional wave.
- The growth rate is very sensitive to:
- Number of daily interactions.
- Personal Hygiene, eg. hand washing, mask wearing.
- Duration of illness
- Number of daily interactions.
-
Social Distancing and extensive testing, both individually and in combination with each other can help significantly slow the spread of disease.
-
Where Social Distancing is impossible, it is better to limit the number of occupants.
-
Reducing transit between communities can further protect those that are unaffected, but restrictions must be put in place early.
Controls
Simulation
Choose a Simulation:


MrMucFeet, or Karlik, is considered one of the best drummers in all of Czechoslovakia. He has generously come to us in order to help us become what we dream--become the top band in all of Czechoslovakia. Karlik was born in Germany but moved to Czechoslovakia shortly after his birth. He went to Ada's primary school there and Advatka's Secondary school. However, rather than going to Music school as it was his dream ever since his childhood, Karlik decided to teach himself everything. It has gone a long way as he is in one of the top rising bands in Czechoslovakia.
Bobbor Tenorvich, or Pavlousek, is the creator of this whole group along with Vaclav. His passion in singing started ever since he was child where he would sing for the family at holidays or functions. He was born native to Czechoslovakia and went to school with Vaclav. Pavlousek and Vaclav became really close friends as they went through school and they would make little songs that they would play just for fun.Later on, Pavlousek and Vaclav would both play at talent shows in their school and they would play so good as to get funded by the school themselves to start their own band. With all this money saved up, Pavlousek and Vaclav would play at their first concert at the local theater in their town.
Bobby Smoeyo, or Vaclav, has played the guitar like someone would practice religion. He was born in Czechoslovakia and went to the same school as Pavlousek and they became best of buds throughout the years. They played in concerts after school and eventually ran into Karlik and they instantly realized that they could actually make a living off of this new band that had just been formed. Thus, the Yeetersons were created and they have come a long way since their beginnings 2 years ago.


Ernest Hemingway
A sportsman, a world citizen, and an author
- 1899 - Ernest Miller Hemingway is born in Oak Park, Illinois.
- 1918 - Hemingway volunteers as an ambulance driver in Italy during World War I.
- 1919 - While wounded, Hemingway begins a brief but serious romance with nurse Agnes von Kurowsky. She would inspire the famous relationship of A Farewell to Arms.
- 1921 - Hemingway marries Elizabeth Hadley Richardson, the first of four wives. They promptly move to Paris.
- 1923 - Three Stories and Ten Poems, Hemingway's first novel, is published. Soon after, Hemingway's first son John is born.
- 1926 - Hemingway's first novel, The Sun Also Rises, releases to critical acclaim.
- 1927 - Elizabeth Hadley and Hemingway divorce. Hemingway marries Pauline Pfeiffer only a month later and publishes his short story collection Men Without Women.
- 1928 - Ernest's second son, Patrick, is born in Key West where Hemingway will complete most of his life's writing.
- 1929 - A Farewell to Arms is published, making Hemingway financially independent.
- 1931 - The third and last Hemingway son, Gregory is born.
- 1937 - Hemingway works as a war correspondent during the Spanish Civil War. To Have and Have Not is published.
- 1937 - Hemingway works as a war correspondent during the Spanish Civil War. To Have and Have Not is published.
- 1940 - Pauline Pfeiffer and Hemingway divorce. Hemingway marries Martha Gellhorn less than three weeks later. His novelized account of the Spanish Civil War, For Whom the Bell Tolls is published.
- 1945 - Hemingway and Martha Gellhorn divorce.
- 1946 - Mary Welsh and Ernest Hemingway marry. is published.
- 1952 - The Old Man and the Sea, Hemingway's most successful work, is published in Life magazine.
- 1953 - Ernest Hemingway receives the Pulitzer Prize for The Old Man and the Sea.
- 1940 - Hemingway is awarded the Nobel Prize in Literature.
- 1940 - Struggling with depression and alcoholism, Ernest Hemingway commits suicide with a shotgun at his home in Ketchum, Idaho.
Noteworthy events in Hemingway's life:
"Every man's life ends the same way. It is only the details of how he lived and how he died that distinguish one man from another." -Ernest Hemingway


{include file="./public/static/block/index/head.html"} {include file="./public/static/block/index/leftNav.html"}


Poking around the iNotes HTTP API (Part 2) - Fun with Rhino
The iNotes HTTP API wasn't designed for consumption outside the iNotes web client. This becomes apparent when looking at
To make use of data included in the JavaScript there are 2 possibilities:
Turning the outline information into something Java useful we need to parse the returned JSON, lets see how that works. The Outline is a little more complex that it might seem. The JSON delivers 6 values (in an array) about the outline entries:
Then the code turns out quite lean:
The String
Instead of
Now the challenge: provide a faster way to generate a collection of
Form=l_GetOutline_JSON
or Form=l_JSVars
that return JavaScript and not JSON! The difference? JSON contains data only, while JavaScript contains function
definitions too.
To make use of data included in the JavaScript there are 2 possibilities:
- do some elaborate String operation
- actually run JavaScript
JSON.stringify
or JSON.parse
are missing and need to be added from elsewhere.
Turning the outline information into something Java useful we need to parse the returned JSON, lets see how that works. The Outline is a little more complex that it might seem. The JSON delivers 6 values (in an array) about the outline entries:
- The hierarchical sequence number. Something like 1 or 3.1 or 3.2.1 - depending on the level. The numbers have gaps where entries in the Outline are hidden from the web
- The hierarchy level starting with 0. So Asia\South-East\Singapore would be level 2
- The Label of the entry. Can be different from the actual name of the element
- The full path to the image for that entry. We'll strip that to get the name without a path, so we can use our own icons
- The full URL to that entry. It has the View Label (Name) and its UNID or system name in the string. We need the UNID for the unread count, so we'll extract that
- Can something be dragged there. 1 = Yes, it is a real folder, 0 = probably not, it is a view or a label only. "Probably" since e.g. you should be able to drag into the "Delete" view
Then the code turns out quite lean:
public OutlineInfo getOutlineInfo(String code, String outline) {
ScriptEngine engine = new ScriptEngineManager().getEngineByExtension("js");
engine.eval(code);
Invocable jsFunc = (Invocable) engine;
OutlineInfo result = (OutlineInfo) jsFunc.invokeFunction("getOutlineObject", outline);
return result;
}
The String
code
contains our JavaScript function. In a working system I probably would keep the engine around somewhere to save the spinup time. outline
contains what came back from the call to iNotes. The JavaScript code is equally lean:
function getOutlineObject(raw) {
importPackage(com.notessensei.demo);
var arr;
eval("arr = "+raw);
var result = new OutlineInfo();
for (var line in arr.outline) {
var oe = new OutlineEntry(arr.outline[line][0], arr.outline[line][1],
arr.outline[line][2], arr.outline[line][3],
arr.outline[line][4], arr.outline[line][5]);
result.addEntry(oe);
}
return result;
}
Instead of
OutlineInfo
you could use a Java collection to return the value, so I won't list the class here. The OutlineEntry
is more interesting, so you can run the sample yourself:
package com.notessensei.demo;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
public class OutlineEntry {
public static final String DEFAULT_ICON = "outlineentry.gif";
private final String id;
private final int level;
private final String label;
private final String icon;
private final String unid;
private final String url;
private final boolean isDropTarget;
private int unreadCount = 0;
// TODO: do I want it rather by sequence, then a TreeSet would be nice
private final Set<OutlineEntry> children = new LinkedHashSet<OutlineEntry>();
public OutlineEntry(String id, int level) {
this.id = id;
this.level = level;
this.label = ">"+id;
this.icon = DEFAULT_ICON;
this.unid = null;
this.url = null;
this.isDropTarget = false;
}
public OutlineEntry(String id, int level, String label, String iconFullPath, String fullURL, int draggable) {
this.id = id;
this.level = level;
this.label = label;
this.icon = this.extractIcon(iconFullPath);
this.unid = this.extractUNID(fullURL);
this.url = fullURL;
this.isDropTarget = (draggable > 0);
}
private String extractUNID(String fullURL) {
if (fullURL==null || fullURL.equals("") || fullURL.indexOf("s_ViewName;")<0) {
return null;
}
String workString = fullURL.substring(fullURL.indexOf("s_ViewName;")+11)+",";
return workString.substring(0,workString.indexOf(","));
}
private String extractIcon(String iconFullPath) {
if (iconFullPath == null || iconFullPath.equals("")) {
return null;
}
String workString = iconFullPath + "/?OpenImageResource";
String[] split = workString.substring(0,workString.indexOf("/?OpenImageResource")).split("/");
return split[split.length-1];
}
public void addChild(OutlineEntry entry) {
this.children.add(entry);
}
public void addChildren(Collection<OutlineEntry> children) {
this.children.addAll(children);
}
public Collection<OutlineEntry> getChildren() {
return this.children;
}
public String getIcon() {
return this.icon;
}
public String getId() {
return this.id;
}
public String getLabel() {
return this.label;
}
public int getLevel() {
return this.level;
}
public String getParent() {
if (this.level == 0) {
return null;
}
return this.id.substring(0, this.id.lastIndexOf("."));
}
public String getUNID() {
return this.unid;
}
public int getUnreadCount() {
return this.unreadCount;
}
public String getUrl() {
return this.url;
}
public boolean isDropTarget() {
return this.isDropTarget;
}
public void setUnreadCount(int unreadCount) {
this.unreadCount = unreadCount;
}
}
Now the challenge: provide a faster way to generate a collection of
OutlineEntry
objects! The code above takes on my system between 100 and 150msPosted by Stephan H Wissel on 27 November 2014 | Comments (0) | categories: IBM Notes


HeDGe is provided as is, for personal use and amusement. It does not purport to model the complexity of real heraldry, but tries to provide a simple way of creating devices keeping to a basic sub-set of heraldic rules.
HeDGe should work in the latest versions of the following desktop web browsers:
Unfortunately, HeDGe will not yet work in the following web browsers:
which are based on webkit, which apparently has a bug preventing access to the charge library.
It is unlikely to work with current versions of Internet Explorer, which lack support for SVG and other standards.
Grateful acknowledgements are made to:
The source code for HeDGe is now on Github.
A Sleeping Dog web production (last updated ).


public class TrcTaskMgr
extends java.lang.Object
| Modifier and Type | Class and Description |
|---|---|
static interface |
TrcTaskMgr.Task
Any class that is registering a task must implement this interface.
|
static class |
TrcTaskMgr.TaskObject
This class implements TaskObject that will be created whenever a class is registered as a cooperative
multi-tasking task.
|
static class |
TrcTaskMgr.TaskType
These are the task type TrcTaskMgr supports:
|
| Modifier and Type | Field and Description |
|---|---|
static long |
INPUT_THREAD_INTERVAL |
static long |
OUTPUT_THREAD_INTERVAL |
| Modifier and Type | Method and Description |
|---|---|
TrcTaskMgr.TaskObject |
createTask(java.lang.String taskName,
TrcTaskMgr.Task task)
This method creates a TRC task.
|
void |
executeTaskType(TrcTaskMgr.TaskType type,
TrcRobot.RunMode mode)
This method is called by the main robot thread to enumerate the task list and calls all the tasks that matches
the given task type.
|
static TrcTaskMgr |
getInstance()
This method returns the global instance of TrcTaskMgr.
|
void |
printTaskPerformanceMetrics(TrcDbgTrace tracer)
This method prints the performance metrics of all tasks with the given tracer.
|
void |
shutdown()
This method is called at the end of the robot program (FtcOpMode in FTC or FrcRobotBase in FRC) to terminate
all threads if any and remove all task from the task list.
|
void |
terminateAllThreads()
This method is mainly for FtcOpMode to call at the end of the opMode loop because runOpMode could be terminated
before shutdown can be called especially if stopMode code is doing logging I/O (e.g.
|
public static final long INPUT_THREAD_INTERVAL
public static final long OUTPUT_THREAD_INTERVAL
public static TrcTaskMgr getInstance()
public TrcTaskMgr.TaskObject createTask(java.lang.String taskName, TrcTaskMgr.Task task)
taskName
- specifies the task name.task
- specifies the Task interface for this task.public void terminateAllThreads()
public void shutdown()
public void executeTaskType(TrcTaskMgr.TaskType type, TrcRobot.RunMode mode)
type
- specifies the task type to be executed.mode
- specifies the robot run mode.public void printTaskPerformanceMetrics(TrcDbgTrace tracer)
tracer
- specifies the tracer to be used for printing the task performance metrics.


|
Xenomai
3.0.4
|
Services dealing with preemptive multi-tasking. More...
Data Structures | |
| struct | RT_TASK_INFO |
| Task status descriptor. More... | |
Macros | |
| #define | T_LOPRIO 0 |
| Task priorities. More... | |
| #define | T_LOCK __THREAD_M_LOCK |
| Task mode bits. More... | |
| #define | T_WARNSW __THREAD_M_WARNSW |
| Cobalt only, nop over Mercury. More... | |
Functions | |
| int | rt_task_delete (RT_TASK *task) |
| Delete a real-time task. More... | |
| int | rt_task_set_affinity (RT_TASK *task, const cpu_set_t *cpus) |
| Set CPU affinity of real-time task. More... | |
| int | rt_task_start (RT_TASK *task, void(*entry)(void *arg), void *arg) |
| Start a real-time task. More... | |
| int | rt_task_shadow (RT_TASK *task, const char *name, int prio, int mode) |
| Turn caller into a real-time task. More... | |
| int | rt_task_join (RT_TASK *task) |
| Wait on the termination of a real-time task. More... | |
| int | rt_task_wait_period (unsigned long *overruns_r) |
| Wait for the next periodic release point. More... | |
| int | rt_task_sleep (RTIME delay) |
| Delay the current real-time task (with relative delay). More... | |
| int | rt_task_sleep_until (RTIME date) |
| Delay the current real-time task (with absolute wakeup date). More... | |
| int | rt_task_same (RT_TASK *task1, RT_TASK *task2) |
| Compare real-time task descriptors. More... | |
| int | rt_task_suspend (RT_TASK *task) |
| Suspend a real-time task. More... | |
| int | rt_task_resume (RT_TASK *task) |
| Resume a real-time task. More... | |
| RT_TASK * | rt_task_self (void) |
| Retrieve the current task descriptor. More... | |
| int | rt_task_set_priority (RT_TASK *task, int prio) |
| Change the base priority of a real-time task. More... | |
| int | rt_task_set_mode (int clrmask, int setmask, int *mode_r) |
| Change the current task mode. More... | |
| int | rt_task_yield (void) |
| Manual round-robin. More... | |
| int | rt_task_unblock (RT_TASK *task) |
| Unblock a real-time task. More... | |
| int | rt_task_slice (RT_TASK *task, RTIME quantum) |
| Set a task's round-robin quantum. More... | |
| int | rt_task_inquire (RT_TASK *task, RT_TASK_INFO *info) |
| Retrieve information about a real-time task. More... | |
| ssize_t | rt_task_send_timed (RT_TASK *task, RT_TASK_MCB *mcb_s, RT_TASK_MCB *mcb_r, const struct timespec *abs_timeout) |
| Send a message to a real-time task. More... | |
| static ssize_t | rt_task_send_until (RT_TASK *task, RT_TASK_MCB *mcb_s, RT_TASK_MCB *mcb_r, RTIME timeout) |
| Send a message to a real-time task (with absolute scalar timeout). More... | |
| static ssize_t | rt_task_send (RT_TASK *task, RT_TASK_MCB *mcb_s, RT_TASK_MCB *mcb_r, RTIME timeout) |
| Send a message to a real-time task (with relative scalar timeout). More... | |
| int | rt_task_receive_timed (RT_TASK_MCB *mcb_r, const struct timespec *abs_timeout) |
| Receive a message from a real-time task. More... | |
| static int | rt_task_receive_until (RT_TASK_MCB *mcb_r, RTIME timeout) |
| Receive a message from a real-time task (with absolute scalar timeout). More... | |
| static int | rt_task_receive (RT_TASK_MCB *mcb_r, RTIME timeout) |
| Receive a message from a real-time task (with relative scalar timeout). More... | |
| int | rt_task_reply (int flowid, RT_TASK_MCB *mcb_s) |
| Reply to a remote task message. More... | |
| int | rt_task_bind (RT_TASK *task, const char *name, RTIME timeout) |
| Bind to a task. More... | |
| int | rt_task_unbind (RT_TASK *task) |
| Unbind from a task. More... | |
| int | rt_task_create (RT_TASK *task, const char *name, int stksize, int prio, int mode) |
| Create a task with Alchemy personality. More... | |
| int | rt_task_set_periodic (RT_TASK *task, RTIME idate, RTIME period) |
| Make a real-time task periodic. More... | |
| int | rt_task_spawn (RT_TASK *task, const char *name, int stksize, int prio, int mode, void(*entry)(void *arg), void *arg) |
| Create and start a real-time task. More... | |
Services dealing with preemptive multi-tasking.
Each Alchemy task is an independent portion of the overall application code embodied in a C procedure, which executes on its own stack context.
| #define T_LOCK __THREAD_M_LOCK |
Task mode bits.
Referenced by rt_task_set_mode().
| #define T_LOPRIO 0 |
Task priorities.
| #define T_WARNSW __THREAD_M_WARNSW |
Cobalt only, nop over Mercury.
Referenced by rt_task_set_mode().
| int rt_task_bind | ( | RT_TASK * | task, |
| const char * | name, | ||
| RTIME | timeout | ||
| ) |
Bind to a task.
This routine creates a new descriptor to refer to an existing Alchemy task identified by its symbolic name. If the object does not exist on entry, the caller may block until a task of the given name is created.
| task | The address of a task descriptor filled in by the operation. Contents of this memory is undefined upon failure. |
| name | A valid NULL-terminated name which identifies the task to bind to. This string should match the object name argument passed to rt_task_create(), or rt_task_shadow(). |
| timeout | The number of clock ticks to wait for the registration to occur (see note). Passing TM_INFINITE causes the caller to block indefinitely until the object is registered. Passing TM_NONBLOCK causes the service to return immediately without waiting if the object is not registered on entry. |
| int rt_task_create | ( | RT_TASK * | task, |
| const char * | name, | ||
| int | stksize, | ||
| int | prio, | ||
| int | mode | ||
| ) |
Create a task with Alchemy personality.
This service creates a task with access to the full set of Alchemy services. If prio is non-zero, the new task belongs to Xenomai's real-time FIFO scheduling class, aka SCHED_FIFO. If prio is zero, the task belongs to the regular SCHED_OTHER class.
Creating tasks with zero priority is useful for running non real-time processes which may invoke blocking real-time services, such as pending on a semaphore, reading from a message queue or a buffer, and so on.
Once created, the task is left dormant until it is actually started by rt_task_start().
| task | The address of a task descriptor which can be later used to identify uniquely the created object, upon success of this call. |
| name | An ASCII string standing for the symbolic name of the task. When non-NULL and non-empty, a copy of this string is used for indexing the created task into the object registry. |
| stksize | The size of the stack (in bytes) for the new task. If zero is passed, a system-dependent default size will be substituted. |
| prio | The base priority of the new task. This value must be in the [0 .. 99] range, where 0 is the lowest effective priority. |
| mode | The task creation mode. The following flags can be OR'ed into this bitmask: |
| int rt_task_delete | ( | RT_TASK * | task | ) |
Delete a real-time task.
This call terminates a task previously created by rt_task_create().
Tasks created with the T_JOINABLE flag shall be joined by a subsequent call to rt_task_join() once successfully deleted, to reclaim all resources.
| task | The task descriptor. |
| int rt_task_inquire | ( | RT_TASK * | task, |
| RT_TASK_INFO * | info | ||
| ) |
Retrieve information about a real-time task.
Return various information about an Alchemy task. This service may also be used to probe for task existence.
| task | The task descriptor. If task is NULL, the information about the current task is returned. |
| info | The address of a structure the task information will be written to. Passing NULL is valid, in which case the system is only probed for existence of the specified task. |
| int rt_task_join | ( | RT_TASK * | task | ) |
Wait on the termination of a real-time task.
This service blocks the caller in non-real-time context until task has terminated. All resources are released after successful completion of this service.
The specified task must have been created by the same process that wants to join it, and the T_JOINABLE mode flag must have been set on creation to rt_task_create().
Tasks created with the T_JOINABLE flag shall be joined by a subsequent call to rt_task_join() once successfully deleted, to reclaim all resources.
| task | The task descriptor. |
|
inlinestatic |
Receive a message from a real-time task (with relative scalar timeout).
This routine is a variant of rt_task_receive_timed() accepting a relative timeout specification expressed as a scalar value.
| mcb_r | The address of a message control block referring to the receive message area. |
| timeout | A delay expressed in clock ticks. |
References rt_task_receive_timed().
| int rt_task_receive_timed | ( | RT_TASK_MCB * | mcb_r, |
| const struct timespec * | abs_timeout | ||
| ) |
Receive a message from a real-time task.
This service is part of the synchronous message passing support available to Alchemy tasks. The caller receives a variable-sized message from another task. The sender is blocked until the caller invokes rt_task_reply() to finish the transaction.
A basic message control block is used to store the location and size of the data area to receive from the client, in addition to a user-defined operation code.
| mcb_r | The address of a message control block referring to the receive message area. The fields from this control block should be set as follows: |
Upon return, mcb_r->opcode will contain the operation code sent from the remote task using rt_task_send().
| abs_timeout | The number of clock ticks to wait for receiving a message (see note). Passing NULL causes the caller to block indefinitely until a remote task eventually sends a message. Passing { .tv_sec = 0, .tv_nsec = 0 } causes the service to return immediately without waiting if no remote task is currently waiting for sending a message. |
Referenced by rt_task_receive(), and rt_task_receive_until().
|
inlinestatic |
Receive a message from a real-time task (with absolute scalar timeout).
This routine is a variant of rt_task_receive_timed() accepting an absolute timeout specification expressed as a scalar value.
| mcb_r | The address of a message control block referring to the receive message area. |
| abs_timeout | An absolute date expressed in clock ticks. |
References rt_task_receive_timed().
| int rt_task_reply | ( | int | flowid, |
| RT_TASK_MCB * | mcb_s | ||
| ) |
Reply to a remote task message.
This service is part of the synchronous message passing support available to Alchemy tasks. The caller sends a variable-sized message back to a remote task, in response to this task's initial message received by a call to rt_task_receive(). As a consequence of calling rt_task_reply(), the remote task will be unblocked from the rt_task_send() service.
A basic message control block is used to store the location and size of the data area to send back, in addition to a user-defined status code.
| flowid | The flow identifier returned by a previous call to rt_task_receive() which uniquely identifies the current transaction. |
| mcb_s | The address of an optional message control block referring to the message to be sent back. If mcb_s is NULL, the remote will be unblocked without getting any reply data. When mcb_s is valid, the fields from this control block should be set as follows: |
| int rt_task_resume | ( | RT_TASK * | task | ) |
Resume a real-time task.
Forcibly resume the execution of a task which was previously suspended by a call to rt_task_suspend(), if the suspend nesting count decrements to zero.
| task | The task descriptor. |
| int rt_task_same | ( | RT_TASK * | task1, |
| RT_TASK * | task2 | ||
| ) |
Compare real-time task descriptors.
This predicate returns true if task1 and task2 refer to the same task.
| task1 | First task descriptor to compare. |
| task2 | Second task descriptor to compare. |
| RT_TASK * rt_task_self | ( | void | ) |
Retrieve the current task descriptor.
Return the address of the current Alchemy task descriptor.
|
inlinestatic |
Send a message to a real-time task (with relative scalar timeout).
This routine is a variant of rt_task_send_timed() accepting a relative timeout specification expressed as a scalar value.
| task | The task descriptor. |
| mcb_s | The address of the message control block referring to the message to be sent. |
| mcb_r | The address of an optional message control block referring to the reply message area. |
| timeout | A delay expressed in clock ticks. |
References rt_task_send_timed().
| ssize_t rt_task_send_timed | ( | RT_TASK * | task, |
| RT_TASK_MCB * | mcb_s, | ||
| RT_TASK_MCB * | mcb_r, | ||
| const struct timespec * | abs_timeout | ||
| ) |
Send a message to a real-time task.
This service is part of the synchronous message passing support available to Alchemy tasks. The caller sends a variable-sized message to another task, waiting for the remote to receive the initial message by a call to rt_task_receive(), then reply to it using rt_task_reply().
A basic message control block is used to store the location and size of the data area to send or retrieve upon reply, in addition to a user-defined operation code.
| task | The task descriptor. |
| mcb_s | The address of the message control block referring to the message to be sent. The fields from this control block should be set as follows: |
| mcb_r | The address of an optional message control block referring to the reply message area. If mcb_r is NULL and a reply is sent back by the remote task, the reply message will be discarded, and -ENOBUFS will be returned to the caller. When mcb_r is valid, the fields from this control block should be set as follows: |
Upon return, mcb_r->opcode will contain the status code sent back from the remote task using rt_task_reply(), or zero if unspecified.
| abs_timeout | An absolute date expressed in clock ticks, specifying a time limit to wait for the recipient task to reply to the initial message (see note). Passing NULL causes the caller to block indefinitely until a reply is received. Passing { .tv_sec = 0, .tv_nsec = 0 } causes the service to return without blocking in case the recipient task is not waiting for messages at the time of the call. |
Referenced by rt_task_send(), and rt_task_send_until().
|
inlinestatic |
Send a message to a real-time task (with absolute scalar timeout).
This routine is a variant of rt_task_send_timed() accepting an absolute timeout specification expressed as a scalar value.
| task | The task descriptor. |
| mcb_s | The address of the message control block referring to the message to be sent. |
| mcb_r | The address of an optional message control block referring to the reply message area. |
| abs_timeout | An absolute date expressed in clock ticks. |
References rt_task_send_timed().
| int rt_task_set_affinity | ( | RT_TASK * | task, |
| const cpu_set_t * | cpus | ||
| ) |
Set CPU affinity of real-time task.
This calls makes task affine to the set of CPUs defined by cpus.
| task | The task descriptor. If task is NULL, the CPU affinity of the current task is changed. |
| cpus | The set of CPUs task should be affine to. |
| int rt_task_set_mode | ( | int | clrmask, |
| int | setmask, | ||
| int * | mode_r | ||
| ) |
Change the current task mode.
Each Alchemy task has a set of internal flags determining several operating conditions. rt_task_set_mode() takes a bitmask of mode bits to clear for disabling the corresponding modes for the current task, and another one to set for enabling them. The mode bits which were previously in effect before the change can be returned upon request.
The following bits can be part of the bitmask:
These two last flags have no effect over the Mercury core, and are simply ignored.
| clrmask | A bitmask of mode bits to clear for the current task, before setmask is applied. Zero is an acceptable value which leads to a no-op. |
| setmask | A bitmask of mode bits to set for the current task. Zero is an acceptable value which leads to a no-op. |
| mode_r | If non-NULL, mode_r must be a pointer to a memory location which will be written upon success with the previous set of active mode bits. If NULL, the previous set of active mode bits will not be returned. |
| int rt_task_set_periodic | ( | RT_TASK * | task, |
| RTIME | idate, | ||
| RTIME | period | ||
| ) |
Make a real-time task periodic.
Make a task periodic by programing its first release point and its period in the processor time line. task should then call rt_task_wait_period() to sleep until the next periodic release point in the processor timeline is reached.
| task | The task descriptor. If task is NULL, the current task is made periodic. task must belong the current process. |
| idate | The initial (absolute) date of the first release point, expressed in clock ticks (see note). If idate is equal to TM_NOW, the current system date is used. |
| period | The period of the task, expressed in clock ticks (see note). Passing TM_INFINITE stops the task's periodic timer if enabled, then returns successfully. |
| int rt_task_set_priority | ( | RT_TASK * | task, |
| int | prio | ||
| ) |
Change the base priority of a real-time task.
The base priority of a task defines the relative importance of the work being done by each task, which gains conrol of the CPU accordingly.
Changing the base priority of a task does not affect the priority boost the target task might have obtained as a consequence of a priority inheritance undergoing.
| task | The task descriptor. If task is NULL, the priority of the current task is changed. |
| prio | The new priority. This value must range from [T_LOPRIO .. T_HIPRIO] (inclusive) where T_LOPRIO is the lowest effective priority. |
| int rt_task_shadow | ( | RT_TASK * | task, |
| const char * | name, | ||
| int | prio, | ||
| int | mode | ||
| ) |
Turn caller into a real-time task.
Set the calling thread personality to the Alchemy API, enabling the full set of Alchemy services. Upon success, the caller is no more a regular POSIX thread, but a Xenomai-extended thread.
If prio is non-zero, the new task moves to Xenomai's real-time FIFO scheduling class, aka SCHED_FIFO. If prio is zero, the task moves to the regular SCHED_OTHER class.
Running Xenomai tasks with zero priority is useful for running non real-time processes which may invoke blocking real-time services, such as pending on a semaphore, reading from a message queue or a buffer, and so on.
| task | If non-NULL, the address of a task descriptor which can be later used to identify uniquely the task, upon success of this call. If NULL, no descriptor is returned. |
| name | An ASCII string standing for the symbolic name of the task. When non-NULL and non-empty, a copy of this string is used for indexing the task into the object registry. |
| prio | The base priority of the task. This value must be in the [0 .. 99] range, where 0 is the lowest effective priority. |
| mode | The task shadowing mode. The following flags can be OR'ed into this bitmask: |
| int rt_task_sleep | ( | RTIME | delay | ) |
Delay the current real-time task (with relative delay).
This routine is a variant of rt_task_sleep_until() accepting a relative timeout specification.
| delay | A relative delay expressed in clock ticks (see note). A zero delay causes this service to return immediately to the caller with a success status. |
| int rt_task_sleep_until | ( | RTIME | date | ) |
Delay the current real-time task (with absolute wakeup date).
Delay the execution of the calling task until a given date is reached. The caller is put to sleep, and does not consume any CPU time in such a state.
| date | An absolute date expressed in clock ticks, specifying a wakeup date (see note). As a special case, TM_INFINITE is an acceptable value that causes the caller to block indefinitely, until rt_task_unblock() is called against it. Otherwise, any wake up date in the past causes the task to return immediately. |
| int rt_task_slice | ( | RT_TASK * | task, |
| RTIME | quantum | ||
| ) |
Set a task's round-robin quantum.
Set the time credit allotted to a task undergoing the round-robin scheduling. If quantum is non-zero, rt_task_slice() also refills the current quantum for the target task, otherwise, time-slicing is stopped for that task.
In other words, rt_task_slice() should be used to toggle round-robin scheduling for an Alchemy task.
| task | The task descriptor. If task is NULL, the time credit of the current task is changed. task must belong to the current process. |
| quantum | The round-robin quantum for the task expressed in clock ticks (see note). |
| int rt_task_spawn | ( | RT_TASK * | task, |
| const char * | name, | ||
| int | stksize, | ||
| int | prio, | ||
| int | mode, | ||
| void(*)(void *arg) | entry, | ||
| void * | arg | ||
| ) |
Create and start a real-time task.
This service spawns a task by combining calls to rt_task_create() and rt_task_start() for the new task.
| task | The address of a task descriptor which can be later used to identify uniquely the created object, upon success of this call. |
| name | An ASCII string standing for the symbolic name of the task. When non-NULL and non-empty, a copy of this string is used for indexing the created task into the object registry. |
| stksize | The size of the stack (in bytes) for the new task. If zero is passed, a system-dependent default size will be substituted. |
| prio | The base priority of the new task. This value must be in the [0 .. 99] range, where 0 is the lowest effective priority. |
| mode | The task creation mode. See rt_task_create(). |
| entry | The address of the task entry point. |
| arg | A user-defined opaque argument entry will receive. |
| int rt_task_start | ( | RT_TASK * | task, |
| void(*)(void *arg) | entry, | ||
| void * | arg | ||
| ) |
Start a real-time task.
This call starts execution of a task previously created by rt_task_create(). This service causes the started task to leave the initial dormant state.
| task | The task descriptor. |
| entry | The address of the task entry point. |
| arg | A user-defined opaque argument entry will receive. |
| int rt_task_suspend | ( | RT_TASK * | task | ) |
Suspend a real-time task.
Forcibly suspend the execution of a task. This task will not be eligible for scheduling until it is explicitly resumed by a call to rt_task_resume(). In other words, the suspended state caused by a call to rt_task_suspend() is cumulative with respect to the delayed and blocked states caused by other services, and is managed separately from them.
A nesting count is maintained so that rt_task_suspend() and rt_task_resume() must be used in pairs.
Receiving a Linux signal causes the suspended task to resume immediately.
| task | The task descriptor. If task is NULL, the current task is suspended. |
| int rt_task_unbind | ( | RT_TASK * | task | ) |
Unbind from a task.
| task | The task descriptor. |
This routine releases a previous binding to an Alchemy task. After this call has returned, the descriptor is no more valid for referencing this object.
| int rt_task_unblock | ( | RT_TASK * | task | ) |
Unblock a real-time task.
Break the task out of any wait it is currently in. This call clears all delay and/or resource wait condition for the target task.
However, rt_task_unblock() does not resume a task which has been forcibly suspended by a previous call to rt_task_suspend(). If all suspensive conditions are gone, the task becomes eligible anew for scheduling.
| task | The task descriptor. |
| int rt_task_wait_period | ( | unsigned long * | overruns_r | ) |
Wait for the next periodic release point.
Delay the current task until the next periodic release point is reached. The periodic timer should have been previously started for task by a call to rt_task_set_periodic().
| overruns_r | If non-NULL, overruns_r shall be a pointer to a memory location which will be written with the count of pending overruns. This value is written to only when rt_task_wait_period() returns -ETIMEDOUT or success. The memory location remains unmodified otherwise. If NULL, this count will not be returned. |
| int rt_task_yield | ( | void | ) |
Manual round-robin.
Move the current task to the end of its priority group, so that the next equal-priority task in ready state is switched in.


BuildAfrica Reboot
BuildAfrica.org has admittedly been ideal for a long time. I experimented in shifting my blogging to a tumblr site at mattberg.org but quickly became a bit frustrated with tumblr. As part of a personal quest, to see how much of my life I can use github to manage I decided to use this as a chance to learn Jekyll and reboot my blog.
Upon the advice of many, I’ve decided to go back to using buildafrica.org as my primary blog as I’ve used it for over a decade and represents what I am about. mattberg.org might possibly be used as a personal reference site to host my CV, etc. We’ll see.
Finding time to write has been the biggest culprit. Recently, I moved back to Africa and am now based in Nairobi, Kenya where I’ll be for the foreeseable future. My experiences here, I hope will inspire me to write more.
The site design is still a very much a work in progress. For now, I’m just using a fork of Zach Holman’s Jeykll theme called Left. I decided to host this as a static site on S3 after some struggles with github page configurations. To do this I highly recommend following this great tutorial.
So for now my inner geek is happy. I can manage all my site content in github and do all work via the command line. :) Check back later for hopefully some actual content.
comments powered by Disqus


FOURSEASONS
Sign In
Sign Up
Home
Private Retreats
Residences
Meeting & Events
Services
Gifts Cards
About Us
Contact Us
Sign In
Discover
FourSeasons Hotel And Resort


Multi-thread
What in the world is it?
Sorry but JavaScript have nothing to do with multi-thread
Think about it like you have dish to prepare. But instead of prepare it yourself, you have someone lend you a hand.
The dish will be complete in a shorter period of time when you do it alone
In short, you do several stuff simultaneously by running those stuff in several thread instead of run it one by one sequentially
How can it help?
It's almost obvious that multi-thread make things faster
For example you have a unit of work that include two separate task says, A and B:
- Required time sequentially run = time(A) + time(B)
- Required time simultaneously run = max( time(A), time(B) )
So the best we can get out of it is to reduce the required time by a half (when A and B take the same amount of time to run)
But. Nothing come for free
There are several issue you need to solve before jumping in and turn a block of normal code to multi-thread code
-
Shared resource manipulate. Usually there will be stuffs that was shared between theads like cache, configuration, v.v...
and manage those resources require extra care like:
| Code in both thread |
while( ! stack.isEmpty() ){
String url = stack.pop();
...
}
|
| Execution in thread A |
Debug |
Execution in thread B |
| !stack.isEmpty() -> true |
stack.size = 1 |
... |
| ... |
stack.size = 1 |
!stack.isEmpty() -> true |
| stack.pop() |
stack.size = 1 |
... |
| ... |
stack.size = 0 |
stack.pop() |
| ... |
stack.size = 0 |
EmptyStackException... |
-
Locking: using synchronizes keyword to perform locking. It cost time to acquite a lock.
Sometime the lock be hold for a long period (like loop through a huge list) then it block others thread that need access to that list.
Beside, you need to decide the lock level for each lock (class based or instance based).
And be careful cause there is a chance for deadlock every time you using locking.
Tip: turn check-then-act series to atomic operation by locking
| Code in both thread |
while( ! stack.isEmpty() ){
String url = null;
synchronized(...) {
if ( stack.isEmpty() ) {
break;
}
url = stack.pop();
}
...
}
|
| Execution in thread A |
Debug |
Execution in thread B |
| !stack.isEmpty() -> true |
stack.size = 1; lock free |
... |
| ... |
stack.size = 1; lock free |
!stack.isEmpty() -> true |
| gain lock -> success |
stack.size = 1; lock free |
... |
| ... |
stack.size = 1; lock -> A |
gain lock -> failed |
| stack.isEmpty() -> false |
stack.size = 1; lock -> A |
... |
| ... |
stack.size = 1; lock -> A |
waiting on the lock |
| stack.pop() |
stack.size = 1; lock -> A |
... |
| ... |
stack.size = 0; lock -> A |
waiting on the lock |
| release lock |
stack.size = 0; lock -> A |
... |
| ... |
stack.size = 0; lock free |
gain lock -> success |
| ... |
stack.size = 0; lock -> B |
stack.isEmpty() -> true |
| ... |
stack.size = 0; lock -> B |
break |
| ... |
stack.size = 0; lock -> B |
release lock |
-
Immutable: if you have a resource that cannot be changed so that resource don't need any lock.
Cause concurrent access problems (dirty read, lost update, phantom read, ...) do not occur on read-only resource.
So, consider to build immutable shared resource over locking if possible
-
Cancellation/Interuption support.
Cancellation or Interuption react may become useful that save system resource. For exam, after hit a button to perform a complex calculation,
User decide to stop it by hit cancel so the application need a mechanism to stop the calculate thead. Otherwise, the calculate thread will
run wild until the calculation complete or exception occur
-
Exception handling.
If exception was throw in a thread (not main thread). It will not affect main thread at all. The application still running and that exception
may silently fade away without anyone noticed. So in multi-thread environment, exception need extra care too.
-
Work splitting.
-
by nature of work: heavy calculate work, network waiting work, i/o waiting work, v.v....
-
by part of collection: says, you have a list of 10 number need to be process, then having 2 thread with 5 number per thread may help
-
How many thread is reasonable?. There are quite a lot of factor affect the number of thread that give the best result like:
#cpu-core, free amount of RAM, nature of task that run together, ... So you need to adjust-then-test to find out the suitable number of thread
that meet your need
-
Thread creation and manipulation have it own price.
The cost to creat and manage threads maybe far greater than the cost to make your work done. So take time to decide that to create thread
time by time or maintain an amount of thread then feed them with work. In case, you make a thread living around so another problem is
when to stop that thread and if they stopped unexpectly which stratergy to renew them?
Step by step
If you already prepare yourself to face the above problems then it's time to create your own piece of multi-thread code
It quite easy that just solve the above problems, one by one. Others stuff have library supported :P
-
Split the work:
Try to split a single unit of work to multiple independence tasks. That mean each task can be perform separately from others
as soon as the input for it become ready. Split work by nature is a good place to start...
-
Decide which to share: Producer-Consumer like system need a common queue to put/take. Observer like system need a common flag to watch on v.v...
So point out which resource that must be shared among the thread and strategy to manipulate them
-
Design exception handling mechanism: Definitely you don't want any exception silently leak out of the system so spend time for this topic
-
Design cancellation/interruption mechanism: very nice to have
-
Design the thread creation/maintenance mechanism: You can build your own thread pool or rely on library/language support
or whatever meet your need. And you may need to answer the question about 'How many thread is enough?` when build or use a pool
Caching
What is it?
The action that storing data to speed up the later access. The data might be result of earlier computation or other low speed accesss data storage
How can it help?
Retrieve the result from cache will be faster than re-compute the result.
In case, the cache store in higher speed access storage then the access time will be reduce
Should know starter pack
- When to clear/rewrite the cached results?
Caching framework
- EHCache
- MemCached
- Java Caching System
- redis
Step by step apply
-
Choose the cache key: The key ussually the factor that determine the output of computation
(the output will stay the same if those factor have not change)
-
Define cache life cycle: when to store/clear/rewrite cache?
gRPC
What is it?
Remote Procedure Call (RPC) is a protocol that one program can use to request a service from a program
located in another computer on network without having to understand the network's details.>
gRPC is a RPC framework
How can it help?
The payload size for each call will be smaller -> reduce the time that tranfer payload over network
Should know starter pack
...
Step by step apply
...