nlp_architect.solutions.trend_analysis package¶
Subpackages¶
Submodules¶
nlp_architect.solutions.trend_analysis.np_scorer module¶
nlp_architect.solutions.trend_analysis.scoring_utils module¶
-
class
nlp_architect.solutions.trend_analysis.scoring_utils.
CorpusIndex
(documents: list, spans: list)[source]¶ Bases:
object
Text span index class. Holds TF and DF values per span. Text spans are normalized and similar spans are mapped to the same TF DF values.
-
class
nlp_architect.solutions.trend_analysis.scoring_utils.
TextSpanScoring
(documents, spans, min_tf=1)[source]¶ Bases:
object
Text spans scoring class. Contains misc scoring algorithms for scoring text fragments extracted from a corpus.
Parameters: - documents (list) – List of spaCy documents.
- spans (list[list]) – List of spaCy spans representing noun phrases of documents document.
-
doc_text_spans
¶
-
documents
¶
nlp_architect.solutions.trend_analysis.topic_extraction module¶
-
nlp_architect.solutions.trend_analysis.topic_extraction.
create_w2v_model
(text_list_t, text_list_r)[source]¶ Create a w2v model on the given corpora
Parameters: - text_list_t – A list of documents - target corpus (List[String])
- text_list_r – A list of documents - reference corpus (List[String])
-
nlp_architect.solutions.trend_analysis.topic_extraction.
get_urls_from_file
(file)[source]¶ Merge two corpora into a single text file
Parameters: - corpus_a – A folder containing text files (String)
- corpus_b – A folder containing text files (String)
Returns: The path of the unified corpus
-
nlp_architect.solutions.trend_analysis.topic_extraction.
load_text_from_folder
(folder)[source]¶ Load files content into a list of docs (texts)
Parameters: folder – A path to a folder containing text files Returns: A list of documents (List[String])
-
nlp_architect.solutions.trend_analysis.topic_extraction.
load_url_content
(url_list)[source]¶ Load articles content into a list of docs (texts)
Parameters: url_list (List[String]) – A list of urls Returns: A list of documents (List[String])
-
nlp_architect.solutions.trend_analysis.topic_extraction.
main
(corpus_t, corpus_r, single_thread, no_train, url)[source]¶
-
nlp_architect.solutions.trend_analysis.topic_extraction.
noun_phrase_extraction
(docs, parser)[source]¶ Extract noun-phrases from a textual corpus
Parameters: - docs (List[String]) – A list of documents
- parser (SpacyInstance) – Spacy NLP parser
Returns: List of topics with their tf_idf, c_value, language-model scores
-
nlp_architect.solutions.trend_analysis.topic_extraction.
save_scores
(np_result, file_path)[source]¶ Save the result of a topic extraction into a file
Parameters: - np_result – A list of topics with different score types (tfidf, cvalue, freq)
- file_path – The output file path
-
nlp_architect.solutions.trend_analysis.topic_extraction.
train_w2v_model
(data)[source]¶ Train a w2v (skipgram) model using fasttext package
Parameters: data – A path to the training data (String)
-
nlp_architect.solutions.trend_analysis.topic_extraction.
unify_corpora_from_folders
(corpus_a, corpus_b)[source]¶ Merge two corpora into a single text file
Parameters: - corpus_a – A folder containing text files (String)
- corpus_b – A folder containing text files (String)
Returns: The path of the unified corpus
-
nlp_architect.solutions.trend_analysis.topic_extraction.
unify_corpora_from_texts
(text_list_t, text_list_r)[source]¶ Merge two corpora into a single text file
Parameters: - text_list_t – A list of documents - target corpus (List[String])
- text_list_r – A list of documents - reference corpus (List[String])
Returns: The path of the unified corpus
nlp_architect.solutions.trend_analysis.trend_analysis module¶
-
nlp_architect.solutions.trend_analysis.trend_analysis.
analyze
(target_data, ref_data, tar_header, ref_header, top_n=10000, top_n_vectors=500, re_analysis=False, tfidf_w=0.5, cval_w=0.5, lm_w=0)[source]¶ Compare a topics list of a target data to a topics list of a reference data and extract hot topics, trends and clusters. Topic lists can be generated by running topic_extraction.py
Parameters: - target_data – A list of topics with importance scores extracted from the tagret corpus
- ref_data – A list of topics with importance scores extracted from the reference corpus
- tar_header – The header to appear for the target topics graphs
- ref_header – The header to appear for the reference topics graphs
- top_n (int) – Limit the analysis to only the top N phrases of each list
- top_n_vectors (int) – The number of vectors to include in the scatter
- re_analysis (Boolean) – whether a first analysis has already been made or not
- tfidf_w (Float) – the TF_IDF weight for the final score calculation
- cval_w (Float) – the C_Value weight for the final score calculation
- lm_w (Float) – the Language-Model weight for the final score calculation
-
nlp_architect.solutions.trend_analysis.trend_analysis.
calc_scores
(scores_file, tfidf_w, cval_w, lm_w, output_path)[source]¶ - Given a topic list with tf_idf,c_value,language_model scores, compute
- a final score for each phrases group according to the given weights
Parameters: - scores_file (String) – A path to the file with groups and raw scores
- tfidf_w (Float) – the TF_IDF weight for the final score calculation
- cval_w (Float) – the C_Value weight for the final score calculation
- lm_w (Float) – the Language-Model weight for the final score calculation
- output_path – A path for the output file of final scores (String)
-
nlp_architect.solutions.trend_analysis.trend_analysis.
clean_group
(phrase_group)[source]¶ Returns the shortest element in a group of phrases
- Args:
- phrase_group (String): a group of phrases separated by ‘;’
- Returns:
- The shortest phrase in the group (String)
-
nlp_architect.solutions.trend_analysis.trend_analysis.
compute_scatter_subwords
(top_groups, w2v_loc)[source]¶ Compute 2D vectors of the provided phrases groups
Parameters: - top_groups – A list of group-representative phrases (List(String))
- w2v_loc – A path to a w2v model (String)
Returns: A tuple (phrases, x, y, n) WHERE: phrases: A list of phrases that are part of the model x: A DataFrame column as the x values of the phrase vector y: A DataFrame column as the y values of the phrase vector n: The number of computed vectors
-
nlp_architect.solutions.trend_analysis.trend_analysis.
merge_phrases
(data, is_ref_data, hash2group, rep2rank, top_n, topics_count)[source]¶ Analyze the provided topics data and detect trends (changes in importance)
Parameters: - data – A list of topics with importance scores
- is_ref_data (Boolean) – Was the data extracted from the target/reference corpus
- hash2group – A dictionary storing the data of each topic
- rep2rank – A dict of all groups representatives and their ranks
- top_n (int) – Limit the analysis to only the top N phrases of each list
- topics_count (int) – The total sum of all topics extracted from both corpora


Overview
While high-level templating systems can be used with Twisted (for
example, Divmod
Nevow, sometimes one needs a less file-heavy system which lets one
directly write HTML. While
ResourceScript
is
available, it has a high coding overhead, and requires some boring string
arithmetic.
ResourceTemplate
fills the
space between Nevow and ResourceScript using Quixote's PTL (Python Templating
Language).
ResourceTemplates need Quixote
installed. In Debian, that means
installing the python-quixote
package
(apt-get install python-quixote
). Other operating systems
require other ways to install Quixote, or it can be done manually.
Configuring Twisted Web
The easiest way to get Twisted Web to support ResourceTemplates is to
bind them to some extension using the web tap's --processor
flag. Here is an example:
% twistd web --path=/var/www \ --processor=.rtl=twisted.web.script.ResourceTemplate
The above command line binds the rtl
extension to use the
ResourceTemplate processor. Other ways are possible, but would require
more Python coding and are outside the scope of this HOWTO.
Using ResourceTemplate
ResourceTemplates are coded in an extension of Python called the
Python Templating Language
. Complete documentation of the PTL
is available
at the
quixote web site. The web server will expect the PTL source file
to define a variable named resource
. This should be
a twisted.web.resource.Resource
,
whose .render
method be called. Usually, you would want
to define render
using the keyword template
rather than def
.
Here is a simple example for a resource template.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
from twisted.web.resource import Resource def getQuote(): return "An apple a day keeps the doctor away." class QuoteResource(Resource): template render(self, request): """\  <title>Quotes Galore</title>
Quotes
""" getQuote() "" resource = QuoteResource()


| Fig 1 |
Summary of bluetongue virus occurrences (yellow points) avai ... |
| Fig 2 |
Current potential distribution map for bluetongue virus base ... |
| Fig 3 |
Relationship of additional independent BTV records to areas ... |
| Fig 4 |
Predicted potential distribution maps for bluetongue virus u ... |
| Fig 5 |
Summary of the modeled global distribution of bluetongue vir ... |


Home
Computer Basics
GRAMMY GOOGLES
LEARN TECHNOLOGY
Go Home
Computer Basics
Topic 1
Topic 2
Topic 3
Topic 4


--- layout: post title: Atom and Optimistic Concurrency tags: [] status: publish type: post published: true meta: _edit_last: '1' dsq_thread_id: '17413766' ---
Elias illustrates some thoughts about optimistic concurrency control and announces that Queso now implements OCC...
What does OCC as described by Google gives us? In my opinion, it takes Atom Protocol implementors (client and server) closer to a level where they can start thinking about merge procedures but they are not there yet.
Elias Torres » Blog Archive » Optimistic Concurrency - Where is your merge code?
The post reminded me of several questions I had when Google announced GData that I need to follow up on. If anybody has thoughts, please post.


Units (skhep.units)¶
Package for physical units and commonly-used unit prefixes.
In HEP the standard set of basic units was originally defined by the [CLHEP] project:
| Quantity | Name | Unit |
|---|---|---|
| Length | millimeter | mm |
| Time | nanosecond | ns |
| Energy | Mega electron Volt | MeV |
| Positron charge | eplus | |
| Temperature | kelvin | K |
| Amount of substance | mole | mol |
| Luminous intensity | candela | cd |
| Plane angle | radian | rad |
| Solid angle | steradian | sr |
It is largely based on the international system of units ([SI])
Quantity Name Unit Length meter m Time second s Mass kilogram kg Electric current ampere A Temperature kelvin K Amount of substance mole mol Luminous intensity candela cd
but augments it with handy definitions as well as changing the basic length and time units.
Typical use cases:
>>> # add two quantities with length units and get the result im meters
>>> from skhep import units as u
>>> (1 * u.meter + 5 * u.cm) / u.meter
1.05
>>> from skhep.units import MeV, GeV
>>> massWindow = 100 * MeV # define a 100 MeV mass window
>>> def energy_resolution():
... # returns the energy resolution of 100 MeV
... return 100 * MeV
...
>>> energy_resolution() / GeV # get the energy resolution in GeV
0.1
References
| [CLHEP] | http://proj-clhep.web.cern.ch/proj-clhep/. |
| [SI] | http://www.physics.nist.gov/cuu/Units/index.html. |
Common unit prefixes¶
- SI prefixes [SI_prefixes].
- Binary prefixes [Binary_prefixes].
References
| [SI_prefixes] | https://en.wikipedia.org/wiki/International_System_of_Units#Prefixes. |
| [Binary_prefixes] | https://en.wikipedia.org/wiki/Unit_prefix#Binary_prefixes. |
Module of HEP basic units¶
In HEP the standard set of basic units was originally defined by the CLHEP [1] project. It is:
| Quantity | Name | Unit |
|---|---|---|
| Length | millimeter | mm |
| Time | nanosecond | ns |
| Energy | Mega electron Volt | MeV |
| Positron charge | eplus | |
| Temperature | kelvin | K |
| Amount of substance | mole | mol |
| Luminous intensity | candela | cd |
| Plane angle | radian | rad |
| Solid angle | steradian | sr |
References
| [1] | http://proj-clhep.web.cern.ch/proj-clhep/. |


Pre-sale YGC and airdrop will be started from April 10 to May 20
Pre-sale and Airdrop YGC will be started from April 10 to May 20. The YGC will be sent to you immediately once you join the distribution program. Invite your friends to earn 5% YGC bonus.
Your reference:
Start on May 21, we will listing on Pancake and you can add liquidity to earn YGC!
This project will be start in June. You can farm your YGC to get more bonus from us!
This project will be start in June. You need store your YGC in period to get more bonus!


|
This tutorial aims to show how to use tools, supplied by stm8mu package, to build
program for STM8 MCU. For further examples and more advanced usage look at samples directory of package.
Lets look at simple assembler source file.
1 : .print "=========================================================="
2 : .print "File : led.asm"
3 : .print "Description : Sample program for blink LED on STM8S207C8"
4 : .print "=========================================================="
5 :
6 : .define PC_ODR.w16 $00500A
7 : .define PC_DDR.w16 $00500C
8 : .define PC_CR1.w16 $00500D
9 :
10: ; PC6
11: .define PIN_NUM 6
12:
13: .extern STACK_TOP.w16
14:
15: ;********************************
16: ;* *
17: ;********************************
18: .section "text"
19: jpf start
20: start.w24:
21: ldw X, #STACK_TOP
22: ldw SP, X
23:
24: bset PC_DDR, #PIN_NUM ; Output
25: bset PC_CR1, #PIN_NUM ; Push-pull
26: loop:
27: bset PC_ODR, #PIN_NUM
28: callr delay
29: bres PC_ODR, #PIN_NUM
30: callr delay
31: jra loop
32:
33: ;********************************
34: ;* *
35: ;********************************
36: .define DELAY_VAL_MS 500
37: .define FCPU_HZ {2 * 1000 * 1000}
38: .define LOOP_LENGTH 4
39: .define LOOPS {FCPU_HZ * DELAY_VAL_MS / 1000 / LOOP_LENGTH}
40:
41: delay:
42: pushw X
43: pushw Y
44:
45: ldw Y, #{LOOPS >> 16}.w16
46: ldw X, #{LOOPS & $ffff}.w16
47:
48: delay_dec:
49: decw X
50: jrne delay_dec
51: decw Y
52: jrne delay_dec
53:
54: popw Y
55: popw X
56: ret
At first line we can see ".print" directive.
Print directive can be used to output text, values of constant symbols and expressions during assembling.
There is ".section" directive at line 18. This directive submit following data/instructions to be placed at "text"
section.
To declare constant symbol you can use ".define" directive. Expression to define value of constant symbol can be another constant symbol,
number or arithmetic expression enclosed in "{" "}" brackets.
Instructions syntax are compliant to ST with little differences. Refer to STM8 CPU Programming Manual (PM044) for instructions syntax.
For exact syntax supported by stm8mu_asm look at "samples/asm_syntax/syntax.asm" file.
At line 20 label is defined. Label should have width attribute. Default width, if not specified, is ".w8",
which is shortmem, ".w16" refer to longmem and ".w24" refer to extmem.
To build object file from source invoke following command at command line:
stm8mu_asm --output=led.l0 led.asm
Assembler will create "led.l0" object file which contain position independent code. To make output file, suitable for programming in STM8
memory, this object should be processed by linker. Linker must know how to place data in memory of target. This info supplied by linker-script.
1 : ;
2 : ; Sample linker script for STM8S207C8
3 : ;
4 :
5 : FLASH_START = $8000
6 :
7 : RAM_START = $0000
8 : RAM_SIZE = {6 * 1024}
9 :
10: ; LMA VMA
11: .place "text" FLASH_START FLASH_START
12:
13: STACK_TOP = {RAM_START + RAM_SIZE - 1}
14: .export STACK_TOP
At line 5 declared FLASH_START symbol. This symbol is referenced at line 11.
At line 11 appeared ".place" directive. It is used to map section data to target memory.
There is two addresses used in ".place" directive. LMA address refer to offset of section in image (flash). VMA address
refer to offset of section in target memory.
In this example LMA match VMA for "text" section. In more complex situations, for example,
like "data" section LMA can be differ from VMA.
Look at "samples" directory for more info about linker files.
To build output file from object-files invoke following command at command line:
stm8mu_lkr --script=led.lkr --output=led.s19 led.l0
Linker will create "led.s19" file in motorola S-record format.
You can use "stm8mu_flash" utility to program file to STM8 memory via UART. Target must contain integrated bootloader.
stm8mu_flash --chip=STM8S207C8 --baud=115200 --cport=/dev/ttyUSB0 --input=led.s19 write
|


How to Make an AVI Movie of Your EPANET or EPANET-MSX Simulation
Contents
Synopsis
This example illustrates the use of NetworkMovie and NetworkFrame to animate either a bulk or wall specie, or both, for an Epanet/MSX simulation, and store the result as an *.avi movie
Note that the EPANET and MSX Matlab wrappers must be on your Matlab search path. Matlab will also need to be able to find the epanet and epanet-msx object libraries and header files.
Get the Epanet-MSX Simulation Data
This example uses the Net2.inp and net2-cl2.msx data files from the official MSX repository. Note that an ordinary Epanet simulation can also be used, in which case msxFname='' (see getQualityData for details).
msxFname = '../Test/net2-cl2.msx'; inpFname = '../Test/Net2.inp'; % Animate the bulk chlorine specie bulkSpecieID = 'CL2'; % There is no wall specie wallSpecieID = ''; % Get the simulation data using Epanet or Epanet-MSX [V,L,T,errcode] = getQualityData(bulkSpecieID,wallSpecieID,... msxFname,inpFname); if errcode > 100 disp 'Error in network water quality computations' return end
Specify Movie Parameters
These parameters are described in NetworkFrame()...
fig = []; % Use a new figure window movFname = 'mymovie.avi'; % Movie file name quality = 100; % 0-100 movie quality (related to data compression) fps = 8; % Frame rate - # to display per second PData.c = 'jet'; % colormap - see 'help colormap' PData.logtransv = 'n'; % Do not log transform the data PData.vmin = 0; % min vertex value for plot color mapping PData.vmax = max(max(V)); % max vertex value % PData.logtransl = 'n'; % We're not plotting link data so these are ignored % PData.lmin = min(min(L)); % PData.lmax = max(max(L)); PData.lwidth = 3; % Width of links in points PData.vsize = 4; % Size of vertices in points (0 == omits verts) PData.tsize = 4; % Size of tank/reservoir nodes PData.legend = 'v'; % Show a colorbar legend for vertex data SData = []; % No special node symbols % SData(1...).ivs = []; % Node IDs to annotate with special symbols % SData(1...).vsmarker = []; % Marker symbols % SData(1...).vsmarkersize = []; % Marker symbol sizes % SData(1...).vsmarkercolor = []; % Marker symbol colors
Write the Movie File
NetworkMovie will display the first frame in a figure window and allow you to make adjustments to it (zoom, pan, etc.) before rendering the frames into an AVI movie file.
NetworkMovie(V,L,fig,movFname,quality,fps,inpFname,PData,SData);
Show the Movie
You could display the movie in Matlab as follows, or just use an external viewer...
% mov = aviread(movFname); % h = figure; % axis equal; % movie(h,mov);


There are two variants of FluentAutomation Docs currently for versions 2 and 3.
v2.0 Documentation
v3.0 Documentation


https://templetonpr-fcc-timestamp-ms.herokuapp.com/December%2015,%202015
https://templetonpr-fcc-timestamp-ms.herokuapp.com/1450137600
{ "unix":<PHONE_NUMBER>, "natural": "December 15, 2015" }
Some links for testing:
Please see here for the code and more info.


Use requirejs.undef() to reset, but called before the first require() for the module. Like undefRequire.html, but with another module in the queue. More info.
Check console for messages


Variaties of service
Lorem ipsum dolor sit amet consectetur adipisicing elit. Modi, ipsam! Nihil quo minima nulla atque!
Read MoreAbought Me
I offer you various services: Maintenance and car repair. Changing the oil, oil and fuel filter, Antifreeze, brake pads, Brake fluid, batteries, alternator belt, power steering belt, etc. - Repair of silencers and replacement of silencers. - Body work. Presale inspection and preparation for sale. I will not say that the best, just repair .... . Advantages: No need to wait long for long lines in auto services. Go about your business while I take care of your car ...
Contact Us
If you value your time and money - “Vladislav AM” - just call or write to e-mail.
<EMAIL_ADDRESS>About Our Company
Your car has long been no longer a luxury item, but a means without which it is quite difficult to imagine the comfortable life of a modern person. However, the vehicle always requires quality service and timely repairs.


Problem 3. Occurrences of word
Write a function that reverses the digits of given decimal number.
The search can be case sensitive or case insensitive.
Use function overloading.
You could use Chrome console (F12) or Firebug to see the results.


Select the data period you want to display recommendations for
Conditions
Please select the condition/illness/disease you would like to show data for
Product
Please select the product/medicine/medical equipment you would like to show data for


// Copyright 2014-2023 Bloomberg Finance L.P. // SPDX-License-Identifier: Apache-2.0 // // 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. // bmqa_session.h -*-C++-*- #ifndef INCLUDED_BMQA_SESSION #define INCLUDED_BMQA_SESSION //@PURPOSE: Provide access to the BlazingMQ broker. // //@CLASSES: // bmqa::SessionEventHandler: interface for receiving events asynchronously. // bmqa::Session : mechanism for access to the BlazingMQ broker. // //@DESCRIPTION: This component provides a mechanism, 'bmqa::Session', that // provides access to a message queue broker and an interface, // 'bmqa::SessionEventHandler' for asynchronous notification of events. The // broker manages named, persistent queues of messages. This broker allows a // client to open queues, post messages to them, or retrieve messages from // them. All of these operations take place within the context of the session // opened by the client application. // // Messages received from a broker are communicated to the application by the // session associated with that broker in the form of events (see // 'bmqa_event'). Events can be of two different types: (1) Messages and // message status events ('bmqa::MessageEvent'), or (2) Session or queue // status events ('bmqa::SessionEvent'). // // A 'Session' can dispatch events to the application in either a synchronous // or asynchronous mode. In synchronous mode, the application must call the // 'nextEvent' method in order to obtain events from the 'Session'. In // asynchronous mode, the application must supply a concrete // 'SessionEventHandler' object at construction time. The concrete // 'SessionEventHandler' provided by the application must implement the // 'onSessionEvent' and 'onMessageEvent' methods, which will be called by the // 'Session' every time a session event or a message event is received. Note // that by default, a session created in asynchronous mode creates only one // internal thread to dispatch events, but a different value for number of // threads can be specified in 'bmqt::SessionOptions'. // // A 'Session' is created either in synchronous or in asynchronous mode, and it // will remain in that mode until destruction. Allowing a mix between // synchronous or asynchronous would make the SDK complicated. The only // exceptions are the "start" and "open" operations that must be available in // synchronous or asynchronous version for the convenience of the programmer. // // By default a 'Session' connects to the local broker, which in turn may // connect to a remote cluster based on configuration. // // After a 'bmqa::Session' is started, the application has to open one or // several queues in read and/or write mode. // ///Disclaimer ///---------- // A 'Session' object is a heavy object representing the negotiated TCP session // with the broker, and the entire associated state (opened queues, statistics, // ...). Therefore, sessions should be always reused if possible, preferably // with only *one* session per lifetime of a component/library/task. // Note that at the time of this writing multiplexing of different logical // sessions over the same physical connection is not supported, so in certain // circumstances reuse of the same session across the whole of a single // application will not be possible. For example, if an application uses two // unrelated libraries both of which use BlazingMQ under the hood, they won't // be able to share a session as it stands. // An example of an extreme inefficiency and an abuse of resources is to // create a session ad-hoc every time a message needs to be posted by the same // component. // ///Thread-safety ///------------- // This session object is *thread* *enabled*, meaning that two threads can // safely call any methods on the *same* *instance* without external // synchronization. // ///Connecting to the Broker ///------------------------ // A 'Session' establishes a communication with a broker service using TCP/IP. // Each 'Session' object must be constructed with a 'bmqa::SessionOptions' // object, which provides the necessary information to connect to the broker. // In particular, the 'SessionOptions' object must specify the IP address and // port needed to connect to the broker. The 'SessionOptions' object may also // provide extra parameters for tuning the TCP connection behavior (see // 'bmqa_sessionoptions' for details). // // Note that in most cases the user does not need to explicitly construct a // 'SessionOptions' object: the default constructor for 'SessionOptions' // creates an instance that will connect to the broker service on the local // machine using the standard port. // // Some options can also be provided using environment variables. //: o !BMQ_BROKER_URI!: Corresponds to 'SessionOptions::brokerUri'. //: If this environment variable is set, its value will override the one //: specified in the 'SessionOptions'. // // A 'Session' object is created in an unconnected state. The 'start' or // 'startAsync' method must be called to connect to the broker. Note that // 'start' method is blocking, and returns either after connection to broker // has been established (success), or after specified timeout (failure). // 'startAsync' method, as the name suggests, connects to the broker // asynchronously (i.e., it returns immediately), and the result of the // operation is notified via 'bmqt::SessionEventType::CONNECTED' session event. // // When the 'Session' is no longer needed, the application should call the // 'stop' (blocking) or 'stopAsync' (non-blocking) method to shut down the // 'Session' and disconnect from the broker. Note that destroying a Session // automatically stops it. The session can be restarted with a call to 'start' // or 'startAsync' once it has been fully stopped. // ///Connection loss and reconnection ///-------------------------------- // If the connection between the application and the broker is lost, the // 'Session' will automatically try to reconnect periodically. The 'Session' // will also notify the application of the event of losing the connection via // 'bmqt::SessionEventType::CONNECTION_LOST' session event. // // Once the connection has been re-established with the broker (as a result of // one of the periodic reconnection attempts), the 'Session' will notify the // application via 'bmqt::SessionEventType::RECONNECTED' session event. After // the connection re-establishment, the 'Session' will attempt to reopen the // queues that were in 'OPEN' state prior to connection loss. The 'Session' // will notify the application of the result of reopen operation via // 'bmqt::SessionEventType::QUEUE_REOPEN_RESULT' for each queue. Note that a // reopen operation on a queue may fail (due to broker issue, machine issue, // etc), so the application must keep track on these session events, and stop // posting on a queue that failed to reopen. // // After all reopen operations are complete and application has been notified // with all 'bmqt::SessionEventType::QUEUE_REOPEN_RESULT' events, the 'Session' // delivers a 'bmqt::SessionEventType::STATE_RESTORED' session event to the // application. // ///Example 1 ///- - - - - // The following example illustrates how to create a 'Session' in synchronous // mode, start it, and stop it. //.. // void runSession() // { // bmqt::SessionOptions options; // options.setBrokerUri("tcp://localhost:30114"); // // bmqa::Session session(options); // int res = session.start(); // if (0 != res) { // bsl::cout << "Failed to start session (" << res << ")" // << bsl::endl; // return; // } // bsl::cout << "Session started." << bsl::endl; // // // Open queue in READ or WRITE or READ/WRITE mode, and receive or // // post messages, etc. // // ... // // session.stop(); // } //.. // This example can be simplified because the constructor for 'Session' uses a // default 'SessionOptions' object that will connect to the local broker // service. The example may be rewritten as follow: //.. // void runSession() // { // bmqa::Session session; // using default 'SessionOptions' // int res = session.start(); // if (0 != res) { // bsl::cout << "Failed to start session (" << res << ")" // << bsl::endl; // return; // } // bsl::cout << "Session started." << bsl::endl; // // // Open queue in READ or WRITE or READ/WRITE mode, and receive or // // post messages, etc. // // ... // // session.stop(); // } //.. // ///Processing session events - synchronous mode ///-------------------------------------------- // If the 'Session' is created in synchronous mode, the application needs to // call the 'nextEvent' method on a regular basis in order to receive events. // This method takes an optional wait timeout as a parameter, and it will // return the next available 'Event' from the session's internal event queue or // it will block the calling thread execution until new 'Event' arrives or // until the specified timeout expires. It is safe to call the 'nextEvent' // method from different threads simultaneously: the 'Session' class provides // proper synchronization logic to protect the internal event queue from // corruption in this scenario. // ///Example 2 ///- - - - - // The following example demonstrates how to write a function that queries and // processes events synchronously. In this example the switch form checks the // type of the 'Event' and performs the necessary actions. // // We first define two functions to process 'SessionEvent' and 'MessageEvent'. // These functions return 'true' if we should keep processing events and // 'false' otherwise (i.e., no more events are expected from the 'Session'). //.. // bool processSessionEvent(const bmqa::SessionEvent& event) // { // bool result = true; // switch (event.type()) { // // case bmqt::SessionEventType::e_CONNECTED: // // The connection to the broker is established (as a result // // of a call to the 'start' method). // openQueues(); // startPostingToQueues(); // break; // // case bmqt::SessionEventType::e_DISCONNECTED: // // The connection to the broker is terminated (as a result // // of a call to the 'stop' method). // result = false; // break; // // case bmqt::SessionEventType::e_CONNECTION_LOST: // // The connection to the broker dropped. Stop posting to the queue. // stopPostingToQueues(); // break; // // case bmqt::SessionEventType::e_STATE_RESTORED: // // The connection to the broker has been restored (i.e., all queues // // have been re-opened. Resume posting to the queue. // resumePostingToQueues(); // break; // // case bmqt::SessionEventType::e_CONNECTION_TIMEOUT: // // The connection to the broker has timed out. // result = false; // break; // // case bmqt::SessionEventType::e_ERROR: // // Internal error // bsl::cout << "Unexpected session error: " // << event.errorDescription() << bsl::endl; // break; // // } // end switch // // return result; // } // // bool processMessageEvent(const bmqa::MessageEvent& event) // { // bool result = true; // switch (event.type()) { // // case bmqt::MessageEventType::e_PUSH: { // // Received a 'PUSH' event from the broker. // bmqa::MessageIterator msgIter = event.messageIterator(); // while (msgIter.nextMessage()) { // const bmqa::Message& msg = msgIter.message(); // // Process 'PUSH' msg here (omitted for brevity) // // ... // } // } break; // // case bmqt::MessageEventType::e_ACK: { // // Received an 'ACK' event from the broker. // bmqa::MessageIterator msgIter = event.messageIterator(); // while (msgIter.nextMessage()) { // const bmqa::Message& msg = msgIter.message(); // // Process 'ACK' msg here (omitted for brevity) // // ... // } // } break; // // } // end switch // // return result; // } //.. // // Next, we define a function that handles events synchronously using the // 'processSessionEvent' and 'processMessageEvent' functions. //.. // void handleEventsSynchronously(bmqa::Session *startedSession) // { // bool more = true; // while (more) { // bmqa::Event event = // startedSession->nextEvent(bsls::TimeInterval(2.0)); // if (event.isSessionEvent()) { // more = processSessionEvent(event.sessionEvent()); // } // else { // more = processMessageEvent(event.messageEvent()); // } // } // } //.. // ///Processing session events - asynchronous mode ///--------------------------------------------- // If application wishes to use 'Session' in asynchronous mode, it must pass a // managed pointer to an event handler implementing the 'SessionEventHandler'. // In this case, when 'Session' is started, a thread pool owned by the // 'Session' is also started for processing events asynchronously. The // 'Session' will call event handler's 'onSessionEvent' or 'onMessageEvent' // method every time a session event or a message event is available. // // Note that after the 'Session' is associated with some event handler, this // association cannot be changed or canceled. The event handler will be used // for processing events until the 'Session' object is destroyed. // ///Example 3 ///- - - - - // The following example demonstrates how to implement an event handler and how // to make the 'Session' use an instance of this event handler for processing // events. // // First, we define a concrete implementation of 'SessionEventHandler'. // //.. // class MyHandler: public bmqa::SessionEventHandler { // public: // MyHandler() { } // virtual ~MyHandler() { } // virtual void onSessionEvent(const bmqa::SessionEvent& event); // virtual void onMessageEvent(const bmqa::MessageEvent& event); // }; // // void MyHandler::onSessionEvent(const bmqa::SessionEvent& event) // { // // The implementation is similar to our 'processSessionEvent' function // // defined in the previous example. // processSessionEvent(event); // } // // void MyHandler::onMessageEvent(const bmqa::MessageEvent& event) // { // // The implementation is similar to our 'processMessageEvent' function // // defined in the previous example. // processMessageEvent(event); // } //.. // Next, we define a function that creates a 'Session' using our implementation // of 'SessionEventHandler'. //.. // void runAsyncSession() // { // bslma::ManagedPtr<SessionEventHandler> handlerMp(new MyHandler()); // // bmqa::Session session(handlerMp); // using default 'SessionOptions' // int res = session.start(); // if (0 != res) { // bsl::cout << "Failed to start session (" << res << ")" // << bsl::endl; // return; // } // // // ... // // session.stop(); // } //.. // ///Opening queues ///-------------- // Once the 'Session' has been created and started, the application can use it // to open queues for producing and/or consuming messages. A queue is // associated with a domain. Domain metadata must be deployed in the BlazingMQ // infrastructure prior to opening queues under that domain, because opening a // queue actually loads the metadata deployed for the associated domain. // // The metadata associated with a domain defines various parameters like // maximum queue size and capacity, persistent policy, routing policy, etc. // // Queue are identified by URIs (Unified Resource Identifiers) that must // follow the BlazingMQsyntax, manipulated as 'bmqt::Uri' objects. A queue URI // is typically formatted as follows: //.. // bmq://my.domain/my.queue //.. // Note that domain names are unique in BlazingMQ infrastructure, which makes a // fully qualified queue URI unique too. // // Queues in BlazingMQ infrastructure are created by applications on demand. // Broke creates a queue when it receives an open-queue request from an // application for a queue that does not exist currently. // // Application can open a queue by calling 'openQueue' or 'openQueueAsync' // method on a started session. Application must pass appropriate flags to // indicate if it wants to post messages to queue, consume messages from the // queue, or both. // // Note that 'openQueue' is a blocking method, and returns after specified // queue has been successfully opened (success) or after specified timeout has // expired (failure). 'openQueueAsync' method, as the name suggests, is non // blocking, and the result of the operation is notified via // 'bmqt::SessionEventType::QUEUE_OPEN_RESULT' session event. // ///Example 4 ///- - - - - // The following example demonstrates how to open a queue for posting messages. // The code first opens the queue with appropriate flags, and then uses // 'bmqa::MessageEventBuilder' to build a message event and post to the queue. //.. // // Session creation and startup logic elided for brevity // const char *queueUri = "bmq://my.domain/my.queue"; // bmqa::QueueId myQueueId(1); // ID for the queue // int rc = session.openQueue( // &myQueueId, // queueUri, // bmqt::QueueFlags::e_WRITE | bmqt::QueueFlags::e_ACK, // bsls::TimeInterval(30, 0)); // // if (rc != 0) { // bsl::cerr << "Failed to open queue, rc: " // << bmqt::OpenQueueResult::Enum(rc) // << bsl::endl; // return; // } //.. // Note that apart from 'WRITE' flag, 'ACK' flag has been passed to // 'openQueue' method above. This indicates that application is interested in // receiving 'ACK' notification for each message it posts to the queue, // irrespective of whether or not the message was successfully received by the // broker and posted to the queue. // // Once the queue has been successfully opened for writing, messages can be // posted to the queue for consumption by interested applications. We will use // 'bmqa::MessageEventBuilder' to build a message event. //.. // // Create a message event builder // bmqa::MessageEventBuilder builder; // session.loadMessageEventBuilder(&builder); // // // Create and post a message event containing 1 message // bmqa::Message& msg = builder.startMessage(); // // msg.setCorrelationId(myCorrelationId); // msg.setDataRef(&myPayload); // where 'myPayload' is of type 'bdlbb::Blob' // rc = builder.packMessage(myQueueId); // if (rc != 0) { // bsl::cerr << "Failed to pack message, rc: " // << bmqt::EventBuilderResult::Enum(rc) // << bsl::endl; // return; // } // // // Post message event // rc = session.post(builder.messageEvent()); // if (rc != 0) { // bsl::cerr << "Failed to post message event to the queue, rc: " // << bmqt::PostResult::Enum(rc) // << bsl::endl; // return; // } // // // ... post more messages //.. // ///Closing queues ///-------------- // After an application no longer needs to produce or consume messages from a // queue, it can be closed by 'closeQueue' or 'closeQueueAsync' method. Note // that closing a queue closes an application's "view" on the queue, and may // not lead to queue deletion in the broker. A 'Session' does not expose any // method to explicitly delete a queue. // // Note that 'closeQueue' is a blocking method and returns after the specified // queue has been successfully closed (success) or after specified timeout has // expired (failure). 'closeQueueAsync', as the name suggests, is a // non-blocking method, and result of the operation is notified via // 'bmqt::SessionEventType::e_QUEUE_CLOSE_RESULT' session event. // // There are 3 flavors which behave differently with regard to thread blocking // and callback execution: ///---------------------------------------------------------------------------- // | openQueue | openQueueSync | openQueueAsync // | configureQueue | configureQueueSync | configureQueueAsync // | closeQueue | closeQueueSync | closeQueueAsync // | (deprecated Sync) | (Synchronous) | (Asynchronous) //-----------|-------------------|----------------------|---------------------- // event | unblocks in | unblocks in event | executes callback in // handler | internal thread | handler thread (*) | event handler thread // | | | // nextEvent | unblocks in | unblocks in | executes callback // | internal thread | internal thread | in nextEvent thread //----------------------------------------------------------------------------- // // (*) - guarantees unblocking after all previously enqueued events have been // emitted to the eventHandler, allowing the user to have proper serialization // of events for the given queue (for example no more PUSH messages will be // delivered through the eventHandler for the queue after // configureQueueSync(maxUnconfirmed = 0) returns). // BMQ #include <bmqscm_version.h> #include <bmqa_abstractsession.h> #include <bmqa_closequeuestatus.h> #include <bmqa_configurequeuestatus.h> #include <bmqa_confirmeventbuilder.h> #include <bmqa_messageeventbuilder.h> #include <bmqa_openqueuestatus.h> #include <bmqt_queueoptions.h> #include <bmqt_sessionoptions.h> #include <bmqt_uri.h> // BDE #include <ball_log.h> #include <bsl_memory.h> #include <bsl_string.h> #include <bslma_allocator.h> #include <bslma_managedptr.h> #include <bslma_usesbslmaallocator.h> #include <bslmf_nestedtraitdeclaration.h> #include <bsls_keyword.h> #include <bsls_timeinterval.h> #include <bsls_types.h> namespace BloombergLP { // FORWARD DECLARATION namespace bmqimp { class Application; } namespace bmqimp { class Event; } namespace bmqp { class MessageGUIDGenerator; } namespace bslmt { class Semaphore; } namespace bmqa { // FORWARD DECLARATION class Event; class Message; class MessageEvent; class MessageProperties; class QueueId; class SessionEvent; // ========================= // class SessionEventHandler // ========================= class SessionEventHandler { // Pure protocol for an asynchronous event handler. The implementation // must be thread safe if the 'Session' is configured to use multiple // threads. public: // CREATORS virtual ~SessionEventHandler(); // Destroy this object. // MANIPULATORS virtual void onSessionEvent(const SessionEvent& event) = 0; // Process the specified session 'event' (connected, disconnected, // queue opened, queue closed, etc.). virtual void onMessageEvent(const MessageEvent& event) = 0; // Process the specified message 'event' containing one or more // messages. }; // ================== // struct SessionImpl // ================== struct SessionImpl { // Impl structure for the session data members, so that special task such // as 'bmqadm' can access them by reinterpret casting a 'Session' object. // Care should be taken though since 'Session' is a polymorphic class. // PUBLIC DATA bslma::Allocator *d_allocator_p; // The allocator to use bmqt::SessionOptions d_sessionOptions; // Session options as provided by // the application. bslma::ManagedPtr<SessionEventHandler> d_eventHandler_mp; // Event handler, if any, to use // for notifying application of // events. bsl::shared_ptr<bmqp::MessageGUIDGenerator> d_guidGenerator_sp; // GUID generator object. bslma::ManagedPtr<bmqimp::Application> d_application_mp; // The application object. private: // NOT IMPLEMENTED SessionImpl(const SessionImpl&) BSLS_KEYWORD_DELETED; SessionImpl& operator=(const SessionImpl&) BSLS_KEYWORD_DELETED; public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(SessionImpl, bslma::UsesBslmaAllocator) // CREATORS SessionImpl(const bmqt::SessionOptions& options, bslma::ManagedPtr<SessionEventHandler> eventHandler, bslma::Allocator *allocator = 0); // Create a new object having the specified 'options' and // 'eventHandler' and using the optionally specified 'allocator'. }; // ============= // class Session // ============= class Session: public AbstractSession { // A session with a BlazingMQ broker. public: // TYPES typedef AbstractSession::OpenQueueCallback OpenQueueCallback; // Invoked as a response to an asynchronous open queue operation, // 'OpenQueueCallback' is an alias for a callback function object // (functor) that takes as an argument the specified 'result', // providing the result and context of the requested operation. typedef AbstractSession::ConfigureQueueCallback ConfigureQueueCallback; // Invoked as a response to an asynchronous configure queue operation, // 'ConfigureQueueCallback' is an alias for a callback function object // (functor) that takes as an argument the specified 'result', // providing the result and context of the requested operation. typedef AbstractSession::CloseQueueCallback CloseQueueCallback; // Invoked as a response to an asynchronous close queue operation, // 'CloseQueueCallback' is an alias for a callback function object // (functor) that takes as an argument the specified 'result', // providing the result and context of the requested operation. private: // CLASS-SCOPE CATEGORY BALL_LOG_SET_CLASS_CATEGORY("BMQA.SESSION"); private: // DATA SessionImpl d_impl; // Sole data member of this object. private: // NOT IMPLEMENTED Session(const Session&) BSLS_KEYWORD_DELETED; Session& operator=(const Session&) BSLS_KEYWORD_DELETED; // Copy constructor and assignment operator are not implemented public: // TRAITS BSLMF_NESTED_TRAIT_DECLARATION(Session, bslma::UsesBslmaAllocator) // CREATORS explicit Session(const bmqt::SessionOptions& options = bmqt::SessionOptions(), bslma::Allocator *allocator = 0); // Create a new 'Session' in *synchronous* mode using the optionally // specified 'options'. In such mode, events have to be fetched by the // application using the 'nextEvent()' method. Optionally specify an // 'allocator' used to supply memory. If 'allocator' is 0, the // currently installed default allocator is used. explicit Session(bslma::ManagedPtr<SessionEventHandler> eventHandler, const bmqt::SessionOptions& options = bmqt::SessionOptions(), bslma::Allocator *allocator = 0); // Create a 'Session' in *asynchronous* mode using the specified // 'eventHandler' as callback for event processing and the optionally // specified 'options'. Optionally specify an 'allocator' used to // supply memory. If the optionally specified 'allocator' is 0, the // currently installed default allocator is used. ~Session() BSLS_KEYWORD_OVERRIDE; // Stop the 'Session' and destroy this object. // MANIPULATORS // (virtual bmqa::AbstractSession) ///Session management ///------------------ int start(const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Connect to the BlazingMQ broker and start the message processing for // this 'Session'. This method blocks until either the 'Session' is // connected to the broker, fails to connect, or the operation times // out. If the optionally specified 'timeout' is not populated, use // the one defined in the session options. Return 0 on success, or a // non-zero value corresponding to the 'bmqt::GenericResult::Enum' enum // values otherwise. The behavior is undefined if this method is // called on an already started 'Session'. int startAsync(const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Connect to the BlazingMQ broker and start the message processing for // this 'Session'. This method returns without blocking. The result // of the operation is communicated with a session event. If the // optionally specified 'timeout' is not populated, use the one defined // in the session options. Return 0 on success (this doesn't imply the // session is connected !), or a non-zero value corresponding to the // 'bmqt::GenericResult::Enum' enum values otherwise. The behavior is // undefined if this method is called on an already started 'Session'. void stop() BSLS_KEYWORD_OVERRIDE; // Gracefully disconnect from the BlazingMQ broker and stop the // operation of this 'Session'. This method blocks waiting for all // already invoked event handlers to exit and all session-related // operations to be finished. No other method but 'start()' may be // used after this method returns. This method must *NOT* be called if // the session is in synchronous mode (i.e., not using the // EventHandler), 'stopAsync()' should be called in this case. void stopAsync() BSLS_KEYWORD_OVERRIDE; // Disconnect from the BlazingMQ broker and stop the operation of this // 'Session'. This method returns without blocking and neither enforce // nor waits for any already started session-related operation to be // finished. No method may be used after this method returns. void finalizeStop() BSLS_KEYWORD_OVERRIDE; // **DEPRECATED** // // This method is only to be used if the session is in synchronous mode // (i.e., not using the EventHandler): it must be called once all // threads getting events with 'nextEvent()' have been joined. virtual MessageEventBuilder createMessageEventBuilder(); // Return a MessageEventBuilder that can be used to build message event // for posting on this session. The behavior is undefined unless the // session has been successfully started. Note that lifetime of the // returned object is bound by the lifetime of this session instance // (i.e., returned instance cannot outlive this session instance). // Also note that the 'MessageEventBuilder' objects are pooled, so this // operation is cheap, and 'MessageEventBuilder' can be obtained on // demand and kept on the stack. // // DEPRECATED: Use the 'loadMessageEventBuilder instead. This // method will be marked as 'BSLS_ANNOTATION_DEPRECATED' in // future release of libbmq. void loadMessageEventBuilder(MessageEventBuilder *builder) BSLS_KEYWORD_OVERRIDE; // Load into the specified 'builder' an instance of // 'bmqa::MessageEventBuilder' that can be used to build message event // for posting on this session. The behavior is undefined unless the // session has been successfully started and 'builder' is non-null. // Note that lifetime of the loaded object is bound by the lifetime of // this session instance (i.e., loaded instance cannot outlive this // session instance). Also note that the 'MessageEventBuilder' objects // are pooled, so this operation is cheap, and 'MessageEventBuilder' // can be obtained on demand and kept on the stack. void loadConfirmEventBuilder(ConfirmEventBuilder *builder) BSLS_KEYWORD_OVERRIDE; // Load into the specified 'builder' an instance of // 'bmqa::ConfirmEventBuilder' that can be used to build a batch of // CONFIRM messages for sending to the broker. The behavior is // undefined unless the session has been successfully started and // 'builder' is non-null. Note that the lifetime of the loaded object // is bound by the lifetime of this session instance (i.e., loaded // instance cannot outlive this session instance). void loadMessageProperties(MessageProperties *buffer) BSLS_KEYWORD_OVERRIDE; // Load into the specified 'buffer' an instance of 'MessageProperties' // that can be used to specify and associate properties while building // a 'bmqa::Message'. The behavior is undefined unless the session has // been successfully started and 'buffer' is non-null. Note that // lifetime of the loaded object is bound by the lifetime of this // session instance (i.e., loaded instance cannot outlive this session // instance). ///Queue management ///---------------- int getQueueId(QueueId *queueId, const bmqt::Uri& uri) const BSLS_KEYWORD_OVERRIDE; // Load in the specified 'queueId' the queue corresponding to the // specified 'uri' and return 0 if such a queue was found, or leave // 'queueId' untouched and return a non-zero value if no queue // corresponding to 'uri' is currently open. int getQueueId(QueueId *queueId, const bmqt::CorrelationId& correlationId) const BSLS_KEYWORD_OVERRIDE; // Load in the specified 'queueId' the queue corresponding to the // specified 'correlationId' and return 0 if such a queue was found, or // leave 'queueId' untouched and return a non-zero value if no queue // corresponding to 'correlationId' is currently open. int openQueue(QueueId *queueId, const bmqt::Uri& uri, bsls::Types::Uint64 flags, const bmqt::QueueOptions& options = bmqt::QueueOptions(), const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // DEPRECATED: Use the 'openQueueSync(QueueId *queueId...)' instead. // This method will be marked as // 'BSLS_ANNOTATION_DEPRECATED' in future release of // libbmq. OpenQueueStatus openQueueSync(QueueId *queueId, const bmqt::Uri& uri, bsls::Types::Uint64 flags, const bmqt::QueueOptions& options = bmqt::QueueOptions(), const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Open the queue having the specified 'uri' with the specified 'flags' // (a combination of the values defined in 'bmqt::QueueFlags::Enum'), // using the specified 'queueId' to correlate events related to that // queue. The object 'queueId' referring to is modified, so the // 'queueId' represents the actual queue uri, flags and options. // Return a result providing the status and context of the operation. // Use the optionally specified 'options' to configure some advanced // settings. Note that this operation fails if 'queueId' is // non-unique. If the optionally specified 'timeout' is not populated, // use the one defined in the session options. This operation will // block until either success, failure, or timing out happens. // // THREAD: Note that calling this method from the event processing // thread(s) (i.e., from the EventHandler callback, if // provided) *WILL* lead to a *DEADLOCK*. virtual int openQueue(const QueueId& queueId, const bmqt::Uri& uri, bsls::Types::Uint64 flags, const bmqt::QueueOptions& options = bmqt::QueueOptions(), const bsls::TimeInterval& timeout = bsls::TimeInterval()); // DEPRECATED: Use the 'openQueue(QueueId *queueId...)' instead. This // method will be marked as 'BSLS_ANNOTATION_DEPRECATED' in // future release of libbmq. int openQueueAsync(QueueId *queueId, const bmqt::Uri& uri, bsls::Types::Uint64 flags, const bmqt::QueueOptions& options = bmqt::QueueOptions(), const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // DEPRECATED: Use the 'openQueueAsync(...)' with callback flavor // instead. This method will be marked as // 'BSLS_ANNOTATION_DEPRECATED' in future release of // libbmq. void openQueueAsync(QueueId *queueId, const bmqt::Uri& uri, bsls::Types::Uint64 flags, const OpenQueueCallback& callback, const bmqt::QueueOptions& options = bmqt::QueueOptions(), const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Asynchronously open the queue having the specified 'uri' with the // specified 'flags' (a combination of the values defined in // 'bmqt::QueueFlags::Enum'), using the specified 'queueId' to // correlate events related to that queue and the optionally specified // 'options' to configure some advanced settings. The object 'queueId' // referring to is modified, so the 'queueId' represents the actual // queue uri, flags and options. The result of the operation is // communicated to the specified 'callback' via a // 'bmqa::OpenQueueStatus', providing the status and context of the // requested operation. Note that this operation fails if 'queueId' is // non-unique. If the optionally specified 'timeout' is not populated, // use the one defined in the session options. // // THREAD: The 'callback' will *ALWAYS* be invoked from the // EventHandler thread(s) (or if a SessionEventHandler was not // specified, from the thread invoking 'nextEvent'). int configureQueue(QueueId *queueId, const bmqt::QueueOptions& options, const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // DEPRECATED: Use the 'configureQueueSync(QueueId *queueId...) // instead. This method will be marked as // 'BSLS_ANNOTATION_DEPRECATED' in future release of // libbmq. ConfigureQueueStatus configureQueueSync( const QueueId *queueId, const bmqt::QueueOptions& options, const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Configure the queue identified by the specified 'queueId' using the // specified 'options' and return a result providing the status and // context of the operation. If the optionally specified 'timeout' is // not populated, use the one defined in the session options. This // operation returns error if there is a pending configure for the same // queue. This operation will block until either success, failure, or // timing out happens. // // Note that the following 'bmqt::QueueOptions' fields cannot be // reconfigured after the queue has been opened: // - suspendsOnBadHostHealth // Attempts to reconfigure these fields will yield an 'e_NOT_SUPPORTED' // error code. // // THREAD: Note that calling this method from the event processing // thread(s) (i.e., from the EventHandler callback, if // provided) *WILL* lead to a *DEADLOCK*. int configureQueueAsync( QueueId *queueId, const bmqt::QueueOptions& options, const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // DEPRECATED: Use the 'configureQueueAsync(...)' with callback flavor // instead. This method will be marked as // 'BSLS_ANNOTATION_DEPRECATED' in future release of // libbmq. void configureQueueAsync( const QueueId *queueId, const bmqt::QueueOptions& options, const ConfigureQueueCallback& callback, const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Asynchronously configure the queue identified by the specified // 'queueId' using the specified 'options' to configure some advanced // settings. The result of the operation is communicated to the // specified 'callback' via a 'bmqa::ConfigureQueueStatus', providing // the status and context of the requested operation. If the // optionally specified 'timeout' is not populated, use the one defined // in the session options. // // Note that the following 'bmqt::QueueOptions' fields cannot be // reconfigured after the queue has been opened: // - suspendsOnBadHostHealth // Attempts to reconfigure these fields will yield an 'e_NOT_SUPPORTED' // error code. // // THREAD: The 'callback' will *ALWAYS* be invoked from the // EventHandler thread(s) (or if a SessionEventHandler was not // specified, from the thread invoking 'nextEvent'). int closeQueue(QueueId *queueId, const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // DEPRECATED: Use the 'closeQueueSync(QueueId *queueId...) instead. // This method will be marked as // 'BSLS_ANNOTATION_DEPRECATED' in future release of // libbmq. CloseQueueStatus closeQueueSync(const QueueId *queueId, const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Close the queue identified by the specified 'queueId' and return a // result providing the status and context of the operation. If the // optionally specified 'timeout' is not populated, use the one defined // in the session options. Any outstanding configureQueue request for // this 'queueId' will be canceled. This operation will block until // either success, failure, or timing out happens. Once this method // returns, there is guarantee that no more messages and events for // this 'queueId' will be received. Note that successful processing of // this request in the broker closes this session's view of the queue; // the underlying queue may not be deleted in the broker. When this // method returns, the correlationId associated to the queue is // cleared. // // THREAD: Note that calling this method from the event processing // thread(s) (i.e., from the EventHandler callback, if // provided) *WILL* lead to a *DEADLOCK*. virtual int closeQueue(const QueueId& queueId, const bsls::TimeInterval& timeout = bsls::TimeInterval()); // DEPRECATED: Use the 'closeQueue(QueueId *queueId...) instead. This // method will be marked as 'BSLS_ANNOTATION_DEPRECATED' in // future release of libbmq. int closeQueueAsync(QueueId *queueId, const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // DEPRECATED: Use the 'closeQueueAsync(...)' with callback flavor // instead. This method will be marked as // 'BSLS_ANNOTATION_DEPRECATED' in future release of // libbmq. void closeQueueAsync( const QueueId *queueId, const CloseQueueCallback& callback, const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Asynchronously close the queue identified by the specified // 'queueId'. Any outstanding configureQueue requests will be // canceled. The result of the operation is communicated to the // specified 'callback' via a 'bmqa::CloseQueueStatus', providing the // status and context of the operation. If the optionally specified // 'timeout' is not populated, use the one defined in the session // options. Note that successful processing of this request in the // broker closes this session's view of the queue; the underlying queue // may not be deleted in the broker. The correlationId associated to // the queue remains valid until the 'bmqa::CloseQueueStatus' result // has been received and processed by the 'callback', after which it // will be cleared and no more messages and events for this 'queueId' // will be received. // // THREAD: The 'callback' will *ALWAYS* be invoked from the // EventHandler thread(s) (or if a SessionEventHandler was not // specified, from the thread invoking 'nextEvent'). virtual int closeQueueAsync(const QueueId& queueId, const bsls::TimeInterval& timeout = bsls::TimeInterval()); // DEPRECATED: Use the 'closeQueueAsync(...)' with callback flavor // instead. This method will be marked as // 'BSLS_ANNOTATION_DEPRECATED' in future release of // libbmq. ///Queue manipulation ///------------------ Event nextEvent(const bsls::TimeInterval& timeout = bsls::TimeInterval()) BSLS_KEYWORD_OVERRIDE; // Return the next available event received for this session. If there // is no event available, this method blocks for up to the optionally // specified 'timeout' time interval for an event to arrive. An empty // time interval for 'timeout' (the default) indicates that the method // should not timeout (the method will not return until the next event // is available). Return a 'bmqa::SessionEvent' of type // 'bmqt::SessionEventType::e_TIMEOUT' if a timeout was specified and // that timeout expired before any event was received. Note that this // method can only be used if the session is in synchronous mode (ie // not using the EventHandler). The behavior is undefined unless the // session was started. int post(const MessageEvent& event) BSLS_KEYWORD_OVERRIDE; // Asynchronously post the specified 'event' that must contain one or // more 'Messages'. The return value is one of the values defined in // the 'bmqt::PostResult::Enum' enum. Return zero on success and a // non-zero value otherwise. Note that success implies that SDK has // accepted the 'event' and will eventually deliver it to the broker. // The behavior is undefined unless the session was started. int confirmMessage(const Message& message) BSLS_KEYWORD_OVERRIDE; // Asynchronously confirm the receipt of the specified 'message'. This // indicates that the application is done processing the message and // that the broker can safely discard it from the queue according to // the retention policy set up for that queue. Return 0 on success, // and a non-zero value otherwise. Note that success implies that SDK // has accepted the 'message' and will eventually send confirmation // notification to the broker. int confirmMessage(const MessageConfirmationCookie& cookie) BSLS_KEYWORD_OVERRIDE; // Asynchronously confirm the receipt of the message with which the // specified 'cookie' is associated. This indicates that the // application is done processing the message and that the broker can // safely discard it from the queue according to the retention policy // set up for that queue. Return 0 on success, and a non-zero value // otherwise. Note that success implies that SDK has accepted the // 'message' and will eventually send confirmation notification to the // broker. int confirmMessages(ConfirmEventBuilder *builder) BSLS_KEYWORD_OVERRIDE; // Asynchronously confirm the receipt of the batch of CONFIRM messages // contained in the specified 'builder'. This indicates that the // application is done processing all of the messages and that the // broker can safely discard them from the queue according to the // retention policy set up for that queue. The return value is one of // the values defined in the 'bmqt::GenericResult::Enum' enum. Note // that in case of success, the instance pointed by the 'builder' will // be reset. Also note that success implies that SDK has accepted all // of the messages in 'builder' and will eventually send confirmation // notification to the broker, whereas failure implies that none of the // messages in 'builder' were accepted. Behavior is undefined unless // 'builder' is non-null. ///Debugging related ///----------------- int configureMessageDumping(const bslstl::StringRef& command) BSLS_KEYWORD_OVERRIDE; // Configure this session instance to dump messages to the installed // logger at 'ball::Severity::INFO' level according to the specified // 'command' that should adhere to the following pattern: //.. // IN|OUT|PUSH|ACK|PUT|CONFIRM ON|OFF|100|10s //.. // where each token has a specific meaning: //: o !IN! : incoming ('PUSH' and 'ACK') events //: o !OUT! : outgoing ('PUT' and 'CONFIRM') events //: o !PUSH! : incoming 'PUSH' events //: o !ACK! : incoming 'ACK' events //: o !PUT! : outgoing 'PUT' events //: o !CONFIRM! : outgoing 'CONFIRM' events //: o !ON! : turn on message dumping until explicitly turned off //: o !OFF! : turn off message dumping //: o !100! : turn on message dumping for the next 100 messages //: o !10s! : turn on message dumping for the next 10 seconds // Above, the numerical values '100' and '10' are just for illustration // purposes, and application can choose an appropriate positive numeric // value for them. Also, pattern is case-insensitive. Return zero if // 'command' is valid and message dumping has been configured, non-zero // value otherwise. The behavior is undefined unless the session has // been started. ///Internal ///-------- void *impl(); // Do *NOT* use. Internal function, reserved for BlazingMQ internal // usage. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // ------------- // class Session // ------------- inline int Session::confirmMessage(const Message& message) { return confirmMessage(message.confirmationCookie()); } inline void* Session::impl() { return &d_impl; } } // close package namespace } // close enterprise namespace #endif


The Blockchain is a hot topic for discussion - it has the potential to revolutionise domestic and international transactions - but of course also comes with its disadvantages. The Blockchain was invented in the context of the digital currency, Bitcoin (which by now, most people have heard of). The Blockchain is a public ledger of all the Bitcoin transactions, which continues to grow exponentially. Blockchain allows parties to transact securely in the absence of a third party intermediary and it is clear that some businesses recognise the potential savings connected to Blockchain or other distributed ledger technology.
The term “autonomous things” is being used more and more in the technology world to talk about phenomena powered by the latest advancements in artificial intelligence and machine learning. Autonomous things are things that work autonomously without human guidance or direct intervention.
An immersive experience is an illusory environment that completely surrounds you such that you feel that you are inside it and part of it. The term is associated with technology environments that command the senses such as virtual reality and mixed reality.


GoPro
GoPro HERO4 Session
Live Feed
Screen Capture
Capture a high resolution image from the live feed. The captured images can found
here
Order ID
Capture


Performs a series of statistics on an uploaded savegame and then redirects to a permanent web page with these statistics. A modern browser (IE 10+, Chrome, Firefox, etc) is required. This service is ran for free and without ads because this only costs me $5 a month and I can swallow that; however, the hardware can't take a large load, so please be aware of that.


Molding and Casting
This week assignment is to make the mold and cast of a 3d design using a CNC machine and a piece of CNC wax and some resin.
We went in some trouble with the little CNC machine (software and hardware problems) so I decide to experiment something i see some time ago, and i have to do this at home so i make something really simple but fun.
I try to make a mold using oogoo the diy version of the Sugru, a silicon based material who will dry really fast and have the strength and characteristics of the silicon.
HERE you can find where i take the idea and a starting recipe
The recipe to make the Oogoo is acetic silicon ( important!!! to take the acetic one and not the acrilic) and corn starch.
The corn starch is used to dry up the acetic acid in the silicon and make it dry a lot faster than normal.
I used an out of date corn starch so I didn't waste food!!
the initial quantity are 50% and 50%.
first you have to blend the 2 component using something and make sure the compost take a not really sticky aspect.
When all take a compact look you can go with hands and mix it adding the starch to make it less sticky as you want ( for molding is better a little bit less sticky).
I design and print at home a simple 3d object with my nickname "ZIMO" with tinkercad and down there you can see it and download it.
I used some glycerine hands cream to make the Oogoo don't stick to the 3d printed object and spread it with a brush.
I press the Oogoo around the front face of the 3d printed object and make sure all is really well coated of it.
I let it dry all the night (it is really not necessary because it take like 3 hours to completely dry but I have to time so I wait).
Using careful I separate the 2 pieces.
I use a little bit of starch to make the mold not stick.
I take some IKEA candle and melt the wax with a lighter gently deposit the wax in the mold making sure all the fissure got fully filled.
I let it cool at ambient temperature and after I make a rapid passage ( 5-6 minutes) in the freezer to make the all wax become really strong.
making attention i take out the wax stamp out of the mold ( it is really fragile).
All can I tell is NOT BAD to be an home made mold and casting...
i also made the "standard" molding and casting, in the machining wax.
I design a linear dry bearing to try some composite resin and for test what material is have less friction.
Follow the step in the photo
Catalyst at 5% in weight, 30 minutes pot life
let it dry for a night
50% 50% in volume 7 minutes pot life
30 minutes dry time
the standard resin not charged of any metal powder or other material is really heavy in friction, the static friction is really strong so is not really usefull, maybe with some other add on it wil be better.
Download Rhino file of the linear bearing project for molding and casting


| ${value} Energy Reserved | 50 |
| +${value} Health | 40 65 91 116 142 167 193 218 244 269 295 320 |
| ${value}% Reduction in Poison Duration | 10 11 12 13 14 15 15 16 17 18 19 20 |
| ${value}% Reduction in Vitality Decay Duration | 10 11 12 13 14 15 15 16 17 18 19 20 |
| +${value}% Health | 3 4 5 7 8 9 10 11 12 14 15 16 |
| MaxLevel | 8 |
| UltimateLevel | 12 |


--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/How.20long.20should.20lines.20be.3F.html ---
Are there general guidelines here which I could slavishly follow? One of my co-authors has put some very long lines in the perfectoid project but I don't know whether I should be worried by this.
mathlib wants <= 100.
I think we can follow that.
I think you might be the author of a 151-character line in the perfectoid project :-)
git blame
it
I will happily believe you though (-;
That does look like me (-;
Can I make VS Code punish me if I go over 100 characters?
A recent mathlib update gives me a line in the editor at 100 characters.
https://github.com/leanprover-community/mathlib/blob/master/.vscode/settings.json#L4
:D
I never used to care about this sort of thing, but when I forget my glasses I have to start changing font size and then it becomes an issue.
{% endraw %}Last updated: Apr 24 2020 at 19:02 UTC


| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
HEALTH |
"health" |
public static final String |
MANA |
"mana" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
AMOUNT |
"-particle-amount" |
public static final String |
ANIM_DIR |
"-anim-dir" |
public static final String |
ANIM_SIZE |
"-anim-size" |
public static final String |
ANIMATION |
"-animation" |
public static final String |
DATA |
"-particle-data" |
public static final String |
DX |
"-particle-dx" |
public static final String |
DY |
"-particle-dy" |
public static final String |
DZ |
"-particle-dz" |
public static final String |
INTERVAL |
"-interval" |
public static final String |
MAT |
"-particle-material" |
public static final String |
P_TYPE |
"-particle-type" |
public static final String |
SHAPE |
"-shape" |
public static final String |
SHAPE_DIR |
"-shape-dir" |
public static final String |
SHAPE_SIZE |
"-shape-size" |
public static final String |
SPEED |
"-particle-speed" |
public static final String |
VIEW_RANGE |
"-view-range" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
SPEED |
"velocity" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
COOLDOWN |
"cooldown" |
public static final String |
COST |
"cost" |
public static final String |
INCOMPATIBLE |
"incompatible" |
public static final String |
LEVEL |
"level" |
public static final String |
MANA |
"mana" |
public static final String |
POINTS_SPENT_REQ |
"points-spent-req" |
public static final String |
RANGE |
"range" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
AMOUNT_KEY |
"amount" |
public static final String |
ARRANGEMENT_KEY |
"arrangement" |
public static final String |
DATA_KEY |
"data" |
public static final String |
DIRECTION_KEY |
"direction" |
public static final String |
DX_KEY |
"dx" |
public static final String |
DY_KEY |
"dy" |
public static final String |
DZ_KEY |
"dz" |
public static final String |
LEVEL |
"level" |
public static final String |
MATERIAL_KEY |
"material" |
public static final String |
PARTICLE_KEY |
"particle" |
public static final String |
PARTICLES_KEY |
"particles" |
public static final String |
RADIUS_KEY |
"radius" |
public static final String |
SPEED_KEY |
"speed" |
public static final String |
TYPE_KEY |
"type" |
public static final String |
VISIBLE_RADIUS_KEY |
"visible-radius" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
ABSORB |
"absorb" |
public static final String |
CHANNEL |
"channel" |
public static final String |
CHANNELING |
"channeling" |
public static final String |
DISARM |
"disarm" |
public static final String |
INVINCIBLE |
"invincible" |
public static final String |
ROOT |
"root" |
public static final String |
SILENCE |
"silence" |
public static final String |
STUN |
"stun" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
CUSTOMIZE |
"sapiCustomGUI" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final int |
BIT_MASK |
15 |
public static final int |
BITS |
4 |
public static final int |
MAX_COMBO_SIZE |
8 |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
ATTRIB |
"skillapi.attrib" |
public static final String |
BACKUP |
"skillapi.backup" |
public static final String |
BASIC |
"skillapi.basic" |
public static final String |
CLASS |
"skillapi.class" |
public static final String |
EXP |
"skillapi.exp" |
public static final String |
FORCE |
"skillapi.force" |
public static final String |
GUI |
"skillapi.gui" |
public static final String |
LORE |
"skillapi.lore" |
public static final String |
LVL |
"skillapi.level" |
public static final String |
MANA |
"skillapi.mana" |
public static final String |
POINTS |
"skillapi.points" |
public static final String |
RELOAD |
"skillapi.reload" |
public static final String |
SKILL |
"skillapi.skill" |
public static final String |
WORLD |
"skillapi.world" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final double |
DEG_TO_RAD |
0.017453292519943295 |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
DATA |
"data" |
public static final String |
ID |
"id" |
public static final char |
STRING |
8730 |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
META_KEY |
"sapi_immunity" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
LEVEL |
"sapi_wolf_level" |
public static final String |
SKILL_META |
"sapi_wolf_skills" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
SKILL_TREE |
"sapiSkills" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
BASE |
"Errors." |
public static final String |
CANNOT_USE |
"Errors.cannot-use" |
public static final String |
COOLDOWN |
"Errors.on-cooldown" |
public static final String |
MANA |
"Errors.no-mana" |
public static final String |
NO_SKILLS |
"Errors.no-skills" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
ATTRIB_TITLE |
"GUI.attribute-title" |
public static final String |
BASE |
"GUI." |
public static final String |
CLASS_LIST |
"GUI.skill-class-list" |
public static final String |
PROFESS_TITLE |
"GUI.profess-title" |
public static final String |
SKILL_TREE |
"GUI.skill-tree" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
BASE |
"Notifications." |
public static final String |
CAST |
"Notifications.cast" |
public static final String |
EXP |
"Notifications.gain-exp" |
public static final String |
LOSE |
"Notifications.lose-exp" |
public static final String |
LVL |
"Notifications.gain-lvl" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
ATTRIBUTE_BASE |
"Skill Tree.attribute." |
public static final String |
ATTRIBUTE_CHANGING |
"Skill Tree.attribute.changing" |
public static final String |
ATTRIBUTE_NOT_CHANGING |
"Skill Tree.attribute.not-changing" |
public static final String |
BASE |
"Skill Tree." |
public static final String |
LAYOUT |
"Skill Tree.layout" |
public static final String |
REQUIREMENT_BASE |
"Skill Tree.requirement." |
public static final String |
REQUIREMENT_MET |
"Skill Tree.requirement.met" |
public static final String |
REQUIREMENT_NOT_MET |
"Skill Tree.requirement.not-met" |
public static final String |
TITLE |
"Skill Tree.title" |
public static final String |
TYPE |
"Skill Tree.type" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
PHYSICAL |
"physical" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
ARMOR_STAND |
"asMechanic" |
public static final String |
DISGUISE_KEY |
"sapiDisguiseKey" |
public static final String |
ITEM_PROJECTILE |
"itemProjectile" |
public static final String |
P_CALL |
"pmCallback" |
public static final String |
POTION_PROJECTILE |
"potionProjectile" |
public static final String |
SKILL_CASTER |
"caster" |
public static final String |
SKILL_LEVEL |
"skill_level" |
public static final String |
SPEED_KEY |
"sapiSpeedKey" |
public static final String |
SUMMON_DAMAGE |
"sapiSumDamage" |
| Modifier and Type | Constant Field | Value |
|---|---|---|
public static final String |
ARMOR |
"armor" |
public static final String |
ARMOR_TOUGHNESS |
"armor-toughness" |
public static final String |
ATTACK_SPEED |
"attack-speed" |
public static final String |
COOLDOWN |
"cooldown" |
public static final String |
EXPERIENCE |
"exp" |
public static final String |
HEALTH |
"health" |
public static final String |
HUNGER |
"hunger" |
public static final String |
HUNGER_HEAL |
"hunger-heal" |
public static final String |
KNOCKBACK_RESIST |
"knockback-resist" |
public static final String |
LUCK |
"luck" |
public static final String |
MANA |
"mana" |
public static final String |
MANA_REGEN |
"mana-regen" |
public static final String |
MELEE_DAMAGE |
"melee-damage" |
public static final String |
MELEE_DEFENSE |
"melee-defense" |
public static final String |
MOVE_SPEED |
"move-speed" |
public static final String |
PHYSICAL_DAMAGE |
"physical-damage" |
public static final String |
PHYSICAL_DEFENSE |
"physical-defense" |
public static final String |
PROJECTILE_DAMAGE |
"projectile-damage" |
public static final String |
PROJECTILE_DEFENSE |
"projectile-defense" |
public static final String |
SKILL_DAMAGE |
"skill-damage" |
public static final String |
SKILL_DEFENSE |
"skill-defense" |
Copyright © 2021. All rights reserved.


On the supposed 'Cost' of IoT Botnets...
24 Oct 2016Note: The following article is intended to be highly tongue-in-cheek as it points out the glaringly obvious. I do not condone following any of the hypothetical “instructions” outlined in the thought experiment provided. This information is already known to the crooks out there who are doing nasty things to our internet, so its not like writing about it is going to do anyone any harm… The views expressed here are probably my own (on Tuesdays, at least) and do not represent the views of my cat, my employer, or my priest.
I happened to read an article today on the supposed “cost” of obtaining your very own IoT (Internet of Trash) botnet, with which you can do a whole bunch of nasty criminal things, including, but not limited to, launching absolutely massive DDoS (Distributed Denial of Service) attacks.
This article I read proclaims that you, yes, you, can have your very own DDoS botnet made of IoT devices for $7,500! All you have to do is go shopping on the “dark net” (lol) with some bitcoins, have a decent amount of ill-will towards someone you want to packet into the stone ages, and hey presto, botnet!
Now, on reading this, I laughed a bit. I happen to know a few things, maybe, about the absolutely atrocious state of IoT security, and how trivially abuseable it is.
Anyway, in this bit of writing, I am going to explain why, exactly, the $7,500 figure is an absolute load of bollocks. The real sum of currency required is far, far less. So, to illustrate this, lets step through a hypothetical scenario.

Step 1, obviously, is going to be downloading yourself a copy of the leaked Mirai source code.
Step 2, you go shopping around for a nice, big, server to host your C&C (command and control) server on, at a hosting provider that does not really give a toss about what you do with it. I won’t provide any links to providers, but I found some really, really decent ones for about €40/month that don’t really care what you do with them. I, personally, have used them for internet-scale scanning projects in the past. They also, conveniently, accept Bitcoin. Buy two or three of these, from different providers (there is no shortage!), using different aliases/accounts. This way you can have failover C&C servers.
Step 3, is the “slightly hard bit”. So you have set up your C&C servers with the handy instructions provided in the Mirai source code. You have a nice, redundant setup that should withstand the oncoming onslaught of abuse reports (more on those in a followup post) for a good while. Now you need to have a think about how to gain a competitive edge over literally every single other script kiddie (just like you!) out there who is intending on running their own IoT botnet.
So what do you do, to get a competitive edge? Well, firstly, you tweak the scanner source a bit so that your bots scan faster, and harder, than everyone else. This gives you a slight competitive edge over the other, unmodified botnets, in terms of getting more infections faster.
Next, you look around at some user-manuals for various IoT rubbish that uses Telnet, by using some deeply advanced Google queries, find some more default user/pass combinations to add to the huge list provided in Mirai already. This will allow you to infect exciting new devices that no one else is infecting! Bored 14 year old script-kiddies are already up to this, based on my honeypot logs, so why aren’t you?
For an even greater competitive edge, for the more discerning hacker with an abundance of free time (read as: a couple of days), you could go as far as to make a modified Mirai to scan for SSH as well as Telnet! Suddenly a whole new world of “stuff to infect” is available to you! You can even reuse the same password list! All you have to do is figure out how to cross compile and link libssh, something that a bit of googling stackoverflow should help you accomplish in minutes :)
Step 4, now, Step 4 is the big, scary part. This is where you, young script kiddie, intent on DDoSing the entire planet, get to put on the big-boy pants and unleash fire and brimstone across the entire cybers by launching your malware! However! You need to get yourself some hosts to act as the “patient zeroes” to launch your infection from!
The cheapest - and simplest - way to go about this is to simply hack yourself a few webservers to launch attacks from. Pick a recent Wordpress Plugin exploit, your favourite DirtyCow localroot exploit, a bit of google dorking, and you will have a handful of webservers to use as a base of infection within minutes! You can either simply infect them with the appropriately compiled Mirai binary (yes, it works on badly secured servers too, not just shitty embedded devices), or use them to do telnet/SSH scanning and infecting yourself. With a couple of boxes that have fat pipes as a base of infection, your botnet will grow to absurd numbers in no time!
Step 5, in which you sit back maniacally cackling and stroking a fluffy white cat, commanding your armies of zombified toasters, and demanding “one beeeeelion dollars” to make the DDoS of whatever stop, is left to your imagination.
Step 6 is really quite simple.
So, total cost: 1 week of faffing about (at most), and probably less than €200 in total. Maybe a bit more if you order a heap of pizza while doing it. €200 is a lot less than $7,500, and you get your very own botnet of boxes to launch crimes with.
In conclusion: We are going to see an absolute metric shitload of new Mirai variants cropping up over the next while, as it is an incredibly low-cost and low-effort way to get yourself some absolutely incredible DDoS powers. We are probably also going to see a whole load of poorly thought out and poorly researched articles on “how much an IoT botnet costs”. With this article, I intended to simply head off some of those at the pass by pointing out what every script kiddie out there knows - this stuff is super cheap, super nasty, and, unfortunately, super effective.
f you happen to make some kind of internet connected widget or gizmo that probably shouldn’t have an IP address attached to it but does because it increases its sale value or whatever, maybe you should consider getting its security tested by people who are good at breaking such things. Maybe me? Maybe someone else? Just get it done by someone, before you end up being one of the vendors that is responsible for the next big onslaught of packets screaming across the wire, and are forever remembered for being yet another criminally negligent bunch of incompetents.


Package com.github.twitch4j.helix.domain
Class Prediction
java.lang.Object
com.github.twitch4j.helix.domain.Prediction
public class Prediction
extends java.lang.Object
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
Prediction.PredictionBuilder
-
Constructor Summary
Constructors Constructor Description Prediction()
Prediction(java.lang.String id, java.lang.String broadcasterId, java.lang.String broadcasterName, java.lang.String broadcasterLogin, java.lang.String title, @Nullable java.lang.String winningOutcomeId, java.util.List<PredictionOutcome> outcomes, java.lang.Integer predictionWindowSeconds, PredictionStatus status, java.time.Instant createdAt, @Nullable java.time.Instant endedAt, @Nullable java.time.Instant lockedAt)
-
Method Summary
Modifier and Type Method Description static Prediction.PredictionBuilder
builder()
protected boolean
canEqual(java.lang.Object other)
boolean
equals(java.lang.Object o)
java.lang.String
getBroadcasterId()
ID of the broadcaster.java.lang.String
getBroadcasterLogin()
Login name of the broadcaster.java.lang.String
getBroadcasterName()
Display name of the broadcaster.java.time.Instant
getCreatedAt()
UTC timestamp for the Prediction’s start time.@Nullable java.time.Instant
getEndedAt()
UTC timestamp for when the Prediction ended.java.lang.String
getId()
ID of the Prediction.@Nullable java.time.Instant
getLockedAt()
UTC timestamp for when the Prediction was locked.java.util.List<PredictionOutcome>
getOutcomes()
The possible outcomes for the Prediction.@Nullable java.time.Duration
getPredictionWindow()
java.lang.Integer
getPredictionWindowSeconds()
Total duration for the Prediction (in seconds).PredictionStatus
getStatus()
Status of the Prediction.java.lang.String
getTitle()
Title for the Prediction.java.util.Optional<PredictionOutcome>
getWinningOutcome()
@Nullable java.lang.String
getWinningOutcomeId()
ID of the winning outcome.int
hashCode()
Prediction.PredictionBuilder
toBuilder()
java.lang.String
toString()
Prediction
withBroadcasterId(java.lang.String broadcasterId)
ID of the broadcaster.Prediction
withBroadcasterLogin(java.lang.String broadcasterLogin)
Login name of the broadcaster.Prediction
withBroadcasterName(java.lang.String broadcasterName)
Display name of the broadcaster.Prediction
withCreatedAt(java.time.Instant createdAt)
UTC timestamp for the Prediction’s start time.Prediction
withEndedAt(@Nullable java.time.Instant endedAt)
UTC timestamp for when the Prediction ended.Prediction
withId(java.lang.String id)
ID of the Prediction.Prediction
withLockedAt(@Nullable java.time.Instant lockedAt)
UTC timestamp for when the Prediction was locked.Prediction
withOutcomes(java.util.List<PredictionOutcome> outcomes)
The possible outcomes for the Prediction.Prediction
withPredictionWindowSeconds(java.lang.Integer predictionWindowSeconds)
Total duration for the Prediction (in seconds).Prediction
withStatus(PredictionStatus status)
Status of the Prediction.Prediction
withTitle(java.lang.String title)
Title for the Prediction.Prediction
withWinningOutcomeId(@Nullable java.lang.String winningOutcomeId)
ID of the winning outcome.Methods inherited from class java.lang.Object
clone, finalize, getClass, notify, notifyAll, wait, wait, wait
-
Constructor Details
-
Prediction
public Prediction() -
Prediction
public Prediction(java.lang.String id, java.lang.String broadcasterId, java.lang.String broadcasterName, java.lang.String broadcasterLogin, java.lang.String title, @Nullable @Nullable java.lang.String winningOutcomeId, java.util.List<PredictionOutcome> outcomes, java.lang.Integer predictionWindowSeconds, PredictionStatus status, java.time.Instant createdAt, @Nullable @Nullable java.time.Instant endedAt, @Nullable @Nullable java.time.Instant lockedAt)
-
-
Method Details
-
getPredictionWindow
@Nullable public @Nullable java.time.Duration getPredictionWindow()- Returns:
- the total duration for the Prediction.
-
getWinningOutcome
- Returns:
- the winning PredictionOutcome, in an optional wrapper
-
builder
-
toBuilder
-
withId
ID of the Prediction.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withBroadcasterId
ID of the broadcaster.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withBroadcasterName
Display name of the broadcaster.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withBroadcasterLogin
Login name of the broadcaster.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withTitle
Title for the Prediction. Maximum: 45 characters.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withWinningOutcomeId
ID of the winning outcome. If the status is ACTIVE, this is set to null.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withOutcomes
The possible outcomes for the Prediction. Size must be 2.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withPredictionWindowSeconds
Total duration for the Prediction (in seconds). Minimum: 1. Maximum: 1800.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withStatus
Status of the Prediction.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withCreatedAt
UTC timestamp for the Prediction’s start time.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withEndedAt
UTC timestamp for when the Prediction ended. If the status is ACTIVE, this is set to null.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
withLockedAt
UTC timestamp for when the Prediction was locked. If the status is not LOCKED, this is set to null.- Returns:
- a clone of this object, except with this updated property (returns
this
if an identical value is passed).
-
getId
public java.lang.String getId()ID of the Prediction. -
getBroadcasterId
public java.lang.String getBroadcasterId()ID of the broadcaster. -
getBroadcasterName
public java.lang.String getBroadcasterName()Display name of the broadcaster. -
getBroadcasterLogin
public java.lang.String getBroadcasterLogin()Login name of the broadcaster. -
getTitle
public java.lang.String getTitle()Title for the Prediction. Maximum: 45 characters. -
getWinningOutcomeId
@Nullable public @Nullable java.lang.String getWinningOutcomeId()ID of the winning outcome. If the status is ACTIVE, this is set to null. -
getOutcomes
The possible outcomes for the Prediction. Size must be 2. -
getPredictionWindowSeconds
public java.lang.Integer getPredictionWindowSeconds()Total duration for the Prediction (in seconds). Minimum: 1. Maximum: 1800. -
getStatus
Status of the Prediction. -
getCreatedAt
public java.time.Instant getCreatedAt()UTC timestamp for the Prediction’s start time. -
getEndedAt
@Nullable public @Nullable java.time.Instant getEndedAt()UTC timestamp for when the Prediction ended. If the status is ACTIVE, this is set to null. -
getLockedAt
@Nullable public @Nullable java.time.Instant getLockedAt()UTC timestamp for when the Prediction was locked. If the status is not LOCKED, this is set to null. -
equals
public boolean equals(java.lang.Object o)- Overrides:
equals
in classjava.lang.Object
-
canEqual
protected boolean canEqual(java.lang.Object other) -
hashCode
public int hashCode()- Overrides:
hashCode
in classjava.lang.Object
-
toString
public java.lang.String toString()- Overrides:
toString
in classjava.lang.Object
-


volatile
. Such declarations
may be confusing because accessing the array itself follows the rules for volatile
fields, but accessing the array's contents does not.
Example:
class Data {
private volatile int[] idx = new int[0];
}
If such volatile access is needed for array contents, consider using
java.util.concurrent.atomic
classes instead:
class Data {
private final AtomicIntegerArray idx = new AtomicIntegerArray(new int[0]);
}


So I wrote some tricky semi-mathemetical javascript functions. I was looking for a unit test framework. jsunit had all the features, but it seems still too hard just write a darn test and see the results. My experience if you can't write up a simple unit test and see the results in 30s or have to read a lot of documentation then developers won't use it.
With jsunirunner.js you write a most minimal HTML file, either include your javascript test functions or embed them directly , and write two lines of javscript telling what tests to run. You'll get a clear output of the results.
Oh. You don't like the output format? It's super easy to change. Don't worry about licensing the code... it's free. Plus, the HTML is so minimal you can autogenerate it in your Make/Build system.
Sample test page testSample.js Test Page for CheckDihedral.js


Contents
Freeze drawings
General information
Licensing
Freeze views / drawings
Freeze drawings dialog
Options
Selected views
Export options
Save frozen drawings on the disk