The 10 fastest growing programming languages, according to the Microsoft-owned GitHub
by Business InsiderDevelopers who want to try out new programming languages or projects flock to GitHub, the Microsoft-owned service for sharing code and gathering communities around open source software.
Every year, GitHub publishes a report, called The State of the Octoverse, which tracks the most popular languages and projects on the site. Given GitHub’s prominence in Silicon Valley and anywhere else code is written, the report is a solid proxy for the larger trends in the industry.
While established languages like JavaScript and Java generally dominate the most-popular lists, GitHub also tracks the up-and-coming rising stars – the languages and frameworks that are growing the fastest in usage.
Stephen O’Grady, principal analyst and co-founder of RedMonk, says that he noticed there were three characteristics in these fastest-growing languages.
First, these languages are versatile. For example, Python can be used for machine learning, data science, and other kinds of data-intensive technical tasks. Second of all, some of these new languages, such as Rust and TypeScript, have special features that promote cybersecurity.
“What we hear when we talk to developers, they meant to use tools that will make their applications more secure by design without investing a ton of effort in them,” O’Grady said on-stage at GitHub Universe, the company’s annual event in San Francisco, held last week.
The third is that many of these languages are actually based on, or at least compatible with, those that already exist – which helps them attract a community, drawn from those progenitors. For example, TypeScript has proven popular with JavaScript developers, while Kotlin has been a hit with the Java community.
Here are the fastest-growing programming languages around, according to GitHub:
#10: Go
Go, also known as Golang, is a programming language created at Google by Robert Griesemer, Rob Pike, and Ken Thompson. In 2009, Google released Go as an open source language, meaning it’s free for anyone to use, download, or modify. Go was designed to be especially fast and easy to work with, especially for larger-scale systems (like Google’s own).
#9: Assembly
Assembly is a programming language that “speaks” as directly as possible to computers in their primary language: 0’s and 1’s. Developers use Assembly to write instructions for computers to access and process data at the lowest possible level. It can be tedious because each line of code must include even the simplest of instructions, but it can offers developers an unbeatable level of fine-tuning in their code.
#8: Python
Python is both one of the fastest growing programming languages and the second-most popular one overall. It’s open source, so anybody can download and get started with it, and it’s high-level enough that it’s easy for beginners to pick up. It’s frequently used for tasks around web development, data science, and artificial intelligence.
“We often find that while Python isn’t people’s primary language, it was a lot of people’s second language,” Rachel Potvin, GitHub’s vice president of engineering and data, said onstage at GitHub Universe on Wednesday. “There’s something else behind the uptake in Python which is this explosion of the work in data science and machine learning.”
#7: Apex
Apex was first developed by Salesforce as a language for customizing and building its software, making it easier for developers to write code that automates tasks like updating customer records or running custom reports. It’s designed to work well with large amounts od data, and shares some similarities with Java, one of the most popular programming languages.
#6: PowerShell
PowerShell was developed by Microsoft, and built on its popular and prominent .NET. This open source language helps developers write instructions directly to their computer systems and manage their operating systems – especially useful for IT departments that need to automate tasks like onboarding new users or installing software updates across an entire network. It’s now available on Linux, Apple’s MacOS, and Microsoft’s own Windows.
#5: TypeScript
TypeScript is both one of the fastest-growing programming languages and one of the most popular. Developed by Microsoft, it’s similar to JavaScript, and developers can mix and match both languages. However, compared to JavaScript, it has additional features that help developers create larger-scale software. It’s also supported out of the box by Microsoft’s free code editor Visual Studio Code, which is the top open source project on GitHub.
#4: Kotlin
Kotlin, an open source language, is similar to the popular programming language Java (and programmers can mix and match between the two languages), but it has special features that help guard against bugs. It’s also much more concise, helping developers do more with fewer lines of code. It’s frequently used for building Android apps. Last year, Kotlin was the fastest growing programming language, and it’s used by companies like Google, Square, and Atlassian. It’s still growing fast, as it grew by 182% in the past year.
#3: HCL
HCL, which stands for HashiCorp Configuration Language, was developed by developer startup HashiCorp, which creates tools that help programmers run and secure software running in the cloud. It’s used to help set up HashiCorp’s cloud tools, like Terraform, and it’s designed to be easy for people to read. It grew 213% in the past year.
#2: Rust
Rust was designed to be fast and more efficient with memory, with features that prevent developers from making common errors and introducing bugs. This open source programming language, which is sponsored by Mozilla of Firefox fame, is used in game engines, operating systems, virtual reality, and other systems-intensive tasks. Rust grew 235% in the past year.
#1: Dart
Dart, which was developed by Google, was made specifically for designing user interfaces (UI), or how an app looks and feels to users. It’s similar to JavaScript, the most popular programming language. It’s also used with Google’s Flutter, a UI toolkit for building mobile and web apps. Dart grew 532% in the past year.


Sorting
To sort armor set search results, first click the Sort results... button at top right of the main window.
This opens the sort window. This window is made of two part, the left pane and the right pane.
The left pane
There, you can add sorting logic simply by clicking the Add sorting logic button.
Details comming in the next section.
You can also:
- Make a sorting logic the default one when searching, by clicking the Make active button.
This will also sort the current search result with this sorting logic immediately.
- Sort the current search result with a given logic without making it active, by clicking the Apply button.
The number between parenthesis beside the sorting logic name is the number of sort criteria it contains.
The active sort logic is indicated with blue and bold text on its name.
You can also edit existing sorting logics by clicking the Edit mode button and do:
- Delete existing sorting logics by clicking the X button
- Renamed existing sorting logics by simply typing a new name in the text area
- Move them up or down to reorganize them, by click the the small vertically aligned buttons beside the delete button
The right pane
To use the right pane, you must first select a sorting logic by clicking it.
Then, at top of the right pane, a button named Add sort criteria should appear.
Here you can add as many sort criteria as you want, they are all chained to produce a single sort when searching armor sets.
As for the sorting logics, you can delete some by clicking the X button, and reorganize them by clicking the small vertically aligned buttons.
Selecting multiple search criteria means, for result that are considered equal on the first sort criteria, then the next will sort them on a different criteria, and so on.
For example, let's assume you searched and that produced 4 results:
- Defense: 20, Spare slots: 5
- Defense: 30, Spare slots: 3
- Defense: 30, Spare slots: 4
- Defense: 40, Spare slots: 3
If you add only a Defense sort criteria, this will produce the following:
- Defense: 40, Spare slots: 3
- Defense: 30, Spare slots: 3
- Defense: 30, Spare slots: 4
- Defense: 20, Spare slots: 5
Note that the second and third results have their spare slots not taken into account, and order hasn't changed compared to the original order.
Now let's try to sort by Defense, then by Spare slots, we should get the following result:
- Defense: 40, Spare slots: 3
- Defense: 30, Spare slots: 4
- Defense: 30, Spare slots: 3
- Defense: 20, Spare slots: 5
Now second and third results are in a better order.
That means, for results that were considered equal on Defense, the Spare slots sorting criteria added a level of granularity to produced an even better sorting.
One last example to help you understand the order of sorting: now sorting by Spare slots, then by Defense
- Defense: 20, Spare slots: 5
- Defense: 30, Spare slots: 4
- Defense: 40, Spare slots: 3
- Defense: 30, Spare slots: 3
Note that now the Spare slots is the main criteria, and Defense is a refinement among equal Spare slots results.


T2A01-Collisions-Evan
Player one use WASD to move, E to shoot. Player 2 use 8456 on the numpad to move, 7 to shoot.
The game uses turn based combat, one player makes a move at a time.
...
Player 1 health bar Player 2 health bar


gsweet
Summary
A project for gathering the core methods and tools for making it easier to write scripts across all the products in the gSuite.
Installation
npm i gsweet --save
Basic Use
Once you have your authentication JSON file set up in a file named .env.json
you require the package and call the auth() function
const GSweet = require("gsweet");
const gsweet = new Gsweet();
const { driveOps } = gsweet;
const { sheetOps } = gsweet;
In the above example the lack of a parameter to the new GSweet constructor is telling the package to look for .env.json
at the root of the project. If your credentials file lives somewhere else you can just pass in a relative or absolute path like this
const gsweet = new Gsweet({pathOrVarName:"/Users/your-user-name/dev/ENV_VARS/gsweet.env.json", useExistingEnvVar:false);
const { driveOps } = gsweet;
const { sheetOps } = gsweet;
The second parameter supports using an environment variable that already contains the proper credential string. For example, if you're using Heroku and you have a config var named "GSWEET" the call would be
const gsweet = new GSweet({ pathOrVarName: "GSWEET", useExistingEnvVar: true });
The code that runs loads the JSON file and parses the top level objects into environment variables needed by this package.
A full example usage of the package might look like this
cconst gsweet = new Gsweet({pathOrVarName:"/Users/your-user-name/dev/ENV_VARS/gsweet.env.json", useExistingEnvVar:false);
const { driveOps, sheetOps } = gsweet;
const main = async () => {
// Drive Examples
const TEST_FILE = "<name of sheet in your drive>";
const result = await driveOps.getFiles({
withName: TEST_FILE,
exactMatch: true
});
console.log(result);
// Sheet Examples
const sheetRange = {
id: "<google id of a sheet in your drive>",
range: "Sheet1!A1",
data: [["Test1"], ["Test2"]]
};
const result2 = await sheetOps.setRangeData(sheetRange);
console.log(result2.config.data.values); // just showing the values passed in
console.log("Num Cells Updated:", result2.data.updatedCells);
};
main();
Authentication
If you clone this repo it will not contain the needed authorization pieces. You will need to create a JSON file with the following structure:
"gsweet":{
"client_secrets": {
},
"drive_credentials": {
},
"sheet_credentials": {
}
}
}
If you want to store all of this in an .env
file you will need to turn it into a properly escaped string. A partial example looks like this. Note that all but the starting and ending quote marks need to be escaped. JSON wants double quotes so you can't substitute single quotes.
"gsweet":"{\"client_secrets\":{\"installed\":{\"client_id\"..."
You will need to fill in those objects with the expected json that Google requires. Google has a quick-start on how to create all of these credentials. You can see a full example of the JSOn file in the Reference section of this Readme.
Testing
This package contains both unit tests and integration tests. The integration tests are fragile since they require access to specific files and folders in google drive. The constants for these files are stored in the test-data/integration.json
. Modify that document to contain the names and ids for your files. The expected structure of the test data is
test-folder
---node-test-subfolder
|---doc-in-subfolder
|---sheet-in-subfolder
node-test-sheet
node-test-doc
The top of the integration test files also uses create-env
to load credentials. You will need to change that path to point to your credentials json file.
This project is set up such that unit tests will be written with a test.js
suffix and integration tests will end with testi.js
. You can run unit tests with
npm test
-- the unit testsnpm run test:int
-- the integration testsnpm run test:all
-- both unit and integration tests
Reference on Using the Google Apis
This is information for anyone contributing to (rather than using) this project.
Check out some Drive Samples.
The Drive API
Additional Documentation
This project uses JSDoc comments. If you want to generate the HTML documentation in an /out
folder at the root of the project use:npm run doc
Reference
Full .json.env example
{
"gsweet":{
"client_secrets": {
"installed": {
"client_id": "your id goes here",
"project_id": "your project id",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://accounts.google.com/o/oauth2/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "your client secret",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
]
}
},
"drive_credentials": {
"access_token": "a really long token",
"refresh_token": "a shorter token",
"token_type": "Bearer",
"expiry_date": 123
},
"sheet_credentials": {
"access_token": "your token",
"refresh_token": "the refresh toeken",
"scope": "https://www.googleapis.com/auth/spreadsheets",
"token_type": "Bearer",
"expiry_date": 123
}
}
}
Documentation on GitHub
See the GitHub documentation for the list of available modules, functions, function signatures, and usage examples.


<4 digit year>-<2 digit month>-<2 digit day>-<ti-tle>.md
---
layout: <type that matches a type.html in _layouts>
title: <my-title>
categories: [section, or, whatnot]
tags: [tags, to, associate, for, filters]
etc...
---
<!-- frontmatter -->
This is my really cool content, YAY!
WARNING: Make sure the layout
has a content
tag! Otherwise,
the renderer will not insert the content of the post.


This little utility will connect to Blockfolio using your Token, and will download all your trades to a CSV format. You can find the sourcecode on my Github account chesner. You can use the utility in 2 ways: on this github pages website, or using a CLI. Check out the project's README.md on how to run it.
Because of the limitations of HTTP, you need to use a CORS proxy in order for this utility to work. If you Google for CORS proxy, you'll find several projects that you can use. If the recommended one doesn't work, you can try https://crossorigin.me or https://cors.io/?u=.
I’ve created this tool because I wanted to move my BF data to Delta - but BF doesn’t support import/export (yet?), while this all major competitors are doing so. Delta offers it for free, while Coin-Stats has it as a paid only feature.
This is why I tested it and mainly focussed on the Delta format. You need to install their desktop app, but it works like a charm!
A user reported me that he needed to edit the CSV a bit for his fiat deposits & withdrawals because BF doesn't allow you to specify an exchange when you do. Just look for rows with 'DEPOSIT' and 'WITHDRAW' and fill in the exchange where you deposited to or withdrew from.
Note: I noticed that Deduct from xxx Holdings is pretty broken in BF, when you edit the transaction the according deduct transaction isn't handled pretty well, that's why there's a scoring algorithm that tries to match them, even if you did edits afterwards. I haven't seen these bugs on Delta, since they provide this in their export format natively.
Please report all bugs, issues, ... on the Github project page (https://github.com/chesner/bf2csv/).


LPSnackbarView
open class LPSnackbarView: UIView
The LPSnackbarView
which contains 3 subviews.
titleLabel: The label on the left hand side of the view used to display text.
button: The button on the right hand side of the view which allows an action to be performed.
seperator: A small view which adds an accent that seperates the
titleLabel
and thebutton
.
-
The amount of padding from the left handside, used to layout the
titleLabel
, default is8.0
Declaration
Swift
open var leftPadding: CGFloat = 8.0
-
The amount of padding from the right handside, used to layout the
button
, default is8.0
Declaration
Swift
open var rightPadding: CGFloat = 8.0
-
The height percent of the total available size that the seperator should take up inside the view.
Important
This should only be a value between
0.0
and1.0
. If this value is set past this range, the value will be reset to the default value of0.65
.Declaration
Swift
open var seperatorHeightPercent: CGFloat = 0.65
-
The width for the seperator, default is
1.5
Declaration
Swift
open var seperatorWidth: CGFloat = 1.5
-
The amount of padding from the right side of the seperator (next to the button), default is
20.0
Declaration
Swift
open var seperatorPadding: CGFloat = 20.0
-
Overriden
Declaration
Swift
public override init(frame: CGRect)
-
Overriden
Declaration
Swift
public required init?(coder aDecoder: NSCoder)
-
Overriden, lays out the
seperator
Declaration
Swift
open override func layoutSubviews()
-
Overriden, posts
snackRemoval
notification.Declaration
Swift
open override func removeFromSuperview()
-
The label on the left hand side of the view used to display text.
Declaration
Swift
open lazy var titleLabel: UILabel =
-
The button on the right hand side of the view which allows an action to be performed.


Last updated at 09 Mar 20 17:02 UTC. See https://codefresh.io/steps/ for more details. Next update in 1 hour.
jbadeau/gauge-typescript 0.1.0
Last updated at 09 Mar 20 17:02 UTC. See https://codefresh.io/steps/ for more details. Next update in 1 hour.
jbadeau/gauge-typescript 0.1.0


Start
Prev
Next
2. Make an http connection
Recap and quick check
Before we continue you should have the following running …
ArchivesSpace
Your web browser
Python via IDLE


Toggle navigation
Ophelia's Web Design
Home
About
Contact
Portfolio
About Me
My name is Ophelia...
My children
My family
I am a graduate of Cultivating Coders.I am fortunate to have experienced, and learn many codes and designs.


net time
Used to synchronize the time of a computer.
Options:
\\<computer name> The name of the computer to which synchronize the time
/domain:<domain> Synchronize the time with the specified domain
/set Sets the time


This is a 2D recreation of KSP made with HTML, JS, p5.JS, CSS. (Fairly reduced version)
Press W,A,S,D to move camera around
Press - or + to zoom in our out
Press the arrow keys to add velocity in that direction to the spacecraft (The skyblue square)
Press , or . to slow or speed up the game time
Click on any object to automatically follow it


bernard mairura
Director
Skills
About Me/Why Moringa?
Am a Sage Certified consultant on both the ERP and HRMs systems with a proven record on; Scoping and Analysis, Pre-sales Consulting, Implementation and Training, Project Management and System Support.
I joined Moringa to sharpen my skills on web development applications after seeing the raising need of intergrations of various softwares related to what i do.
Work Eperience
Currently holding the director of Operations position.Some of the clients that are currently linked to our services include; Metropol Group of Companies,International Energy Technik(IET), PG Bison Limited, Jetlak Foods Limited and Egis Limited
Head of Support Department for all Sage products.
Lead consultant in both the Enterprise Resource planning, Payroll and Human Resource consulting serveice which included; Implementation and Support on the Sage Products.
Lead consultant on Payroll,Human Resource and Employee Self service(E.S.S)products.
Education
Introduction to Programming.
Certied Sage products Implementor,SQL Certificate,Sage 300 Certificate.
Certified Public Accountant(CPA-K)
Kenya Certificate of Seconadry Education (KCSE)
Activities


This document describes how to develop a Ninf-G External Module.
Ninf-G implements a function called "External Module." External Module abstracts the functions of Ninf-G and implements the function as a separate process. These functions include (1) invocation of jobs (called "Invoke Server"), (2) communication between Ninf-G Client and Ninf-G Executable (called "Communication Proxy"), (3) Information services of Ninf-G Executable (called "Information Service"). Implementation of these functions depends on the underlying grid middleware. Abstracting the difference of the implementations, External Module provides the same interface for Ninf-G. In order to adopt a new grid middleware, it is required to implement External Module by the grid middleware.
Any user is able to implement an External Module to support a new grid middleware.
Invoke Server, Communication Proxy, and Information Service are External Modules. Some features are common for all External Modules though each External Module has its own feature.
Common feature of External Module is as follows.
External Module is invoked by Ninf-G Client or Ninf-G Executable.
Invoke Server, Client Communication Proxy, Information Service
Remote Communication Proxy
Invoke Server and Communication Proxy are External Modules both of which is related with jobs. In these External Modules, the maximum number of jobs per External Module can be limit by users. If the number of jobs exceeds the limit, a new External Module is invoked.
Ninf-G Client (Ninf-G Executable) and External Module communicate using three pipes which are created by the Ninf-G Client (Ninf-G Executable) when the External Module is invoked. The details of External Module communication protocol is described in Section 2.2.
There are two types of finalization of External Module. Ninf-G Client (1) do not wait or (2) wait, for the termination of External Module after the Ninf-G Client sends an EXIT request to the External Module.
External Module is implemented as a executable or script file
which should be located in the ${NG_DIR}/bin
directory.
It can be located in another directory if External Module is
supplied with an absolute path to the executable file.
Ninf-G Client invokes several processes for the same type of
External Modules. For example, if the API
grpc_config_file_read_np()
is called, a request for creating a
function/object handle or a information query is processed by
a newly invoked process.
Outstanding External Module is only used to handle
existing function/object handles.
Log file for External Module can be specified as an optional argument of the External Module command.
Example:
-l [Log file name]
If this option is specified, External Module outputs logs to the file specified by this argument. Otherwise, logs are not recorded.
External Module must not exit by unexpected optional argument of the command.
A Ninf-G Client(Ninf-G Executable) and External Module exchange three types of messages: Request, Reply, and Notify. A Request message is sent from a Ninf-G Client(Ninf-G Executable) to External Module. Reply and Notify messages are sent from External Module to the Ninf-G Client(Ninf-G Executable). The Ninf-G Client(Ninf-G Executable) assumes that a Reply message must be returned from External Module when the Ninf-G Client (Ninf-G Executable) sends a Request message. A Notify message is used to send messages from External Module to the Ninf-G Client(Ninf-G Executable) asynchronously. Three different pipes are used for sending these three types of message.
| Name | fd | direction | ||
|---|---|---|---|---|
| Request | stdin | Ninf-G Client (Executable) |
----> | External Module |
| Reply | stdout | <---- | ||
| Notify | stderr | <---- |
All messages are sent as plain text. The Return code (<RET>) is 0x0d0a. The Return code is a delimiter that determines the unit of messages.
Request have two types, one is described by one line and the other one is described by multiple lines. Each request has respective type.
In one line type request, parameters for the request is delimited by space character, and the parameter cannot include space characters. The request is expressed as follows:
<Request Name> <Parameter> <Parameter> ...<RET>
On multiple line type request, request name is on the first line. Following lines are expressed as attribute name, space character and attribute value. The attribute name cannot include space character. The end of the request is expressed as "request name _END." The request is expressed as follows:
<Request Name><RET>
<Attribute Name> <Attribute Value><RET>
<Attribute Name> <Attribute Value><RET>
...
<Request Name>_END<RET>
There is one common request on External Module.
The QUERY_FEATURES
request is prepared to query features
implemented on the specific External Module. This request is
issued just after the External Module process invocation.
This request is a one line type request, and have no parameter.
Reply also has two types, one is described by one line and the other one is described by multiple lines. The each reply has respective type.
In one line type reply, return success or failure as a parameter followed by the return value. On successful, "S" is returned followed by a return value. On failure, "F" is returned followed by an error message. The reply is expressed as follows:
S <Return Value> | F <Error Message><RET>
On multiple line type reply, "SM" is returned on the first line. The failure cannot be expressed. Following lines are expressed as attribute name, space character and attribute value. The attribute name cannot include space character. The end of the reply is expressed as "REPLY_END." The request is expressed as follows:
SM<RET>
<Attribute Name> <Attribute Value><RET>
<Attribute Name> <Attribute Value><RET>
...
REPLY_END<RET>
The QUERY_FEATURES
reply is a multiple line type reply.
On the reply, there are 3 type of information.
"protocol_version"
, "feature"
and "request"
are replied.
This specifies the protocol version of External Module. Invoke Server, Communication Proxy, Information Service have respective protocol version. This information can return only one line.
This specifies the extended features that the External Module implements. One feature is on single line and multiple lines can be returned.
This specifies all the requests, that the External Module implements and is responsible. One request is on single line, and multiple lines can be returned.
Notify also has two types as same as Request.
In one line type request, the Notify is expressed as follows:
<Notify Name> <Parameter> <Parameter> ...<RET>
In multiple line type request, the Notify is expressed as follows:
<Notify Name><RET>
<Attribute Name> <Attribute Value><RET>
<Attribute Name> <Attribute Value><RET>
...
<Notify Name>_END<RET>
A Ninf-G Client invokes a Ninf-G Executable on the server machine when a function requiring initialization of function/object handles, such as grpc_function_handle_init(), is called. Ninf-G, Version 2, implements the remote process invocation using the Globus Toolkit's Pre-WS GRAM feature. Implemented using the Globus API, the invocation mechanism has been embedded in Ninf-G. In order to utilize other systems, such as WS GRAM, UNICORE, or Condor for remote process invocation, Ninf-G, Version 5, implements the invocation mechanism as a separate module called "Invoke Server." This design enables users and developers to implement and add a new Invoke Server that can utilize any job invocation mechanism.
Ninf-G Version 5.0.0 includes the following Invoke Servers:
Here is a typical flow of a Ninf-G Client application:
Initializes data structures used by the Ninf-G Client.
Creates a function/object handle which requests remote process invocation. The request will be processed and a Ninf-G Executable will be created on the server machine. When the Ninf-G Executable is created, it connects to the Ninf-G Client to establish a TCP connection between the Ninf-G Executable and the Ninf-G Client.
Calls the remote function, i.e. (3.1) the Ninf-G Client sends arguments to the Ninf-G Executable, (3.2) the Ninf-G Executable performs some form of computation, and (3.3) the Ninf-G Executable sends the results to the Ninf-G Client.
Requests the Ninf-G Executable to terminate its process. If an error occurs during the termination, the Ninf-G Client requests the Invoke Server to kill the Ninf-G Executable.
Frees the data structures used by the Ninf-G Client.
Invoke Server is required to implement initialization and finalization of the function/object handles which are described in steps (2) and (4).
The only requirement for underlying middleware is that the middleware must be capable of remote process invocation. Examples of such middleware include the Globus Toolkit Pre-WS GRAM, Globus Toolkit WS GRAM, UNICORE, Condor, and SSH.
Invoke Server is an adapter for the underlying middleware and it
handles requests from a Ninf-G Client.
Invoke Server analyzes and processes the request sent from
the Ninf-G Client and replies to the Ninf-G Client.
For example, if Invoke Server receives a JOB_CREATE
request from the Ninf-G Client, Invoke Server creates a Job ID,
returns the Job ID to the Ninf-G Client,
and invokes the job processes called for in the request.
Invoke Server can be implemented using any language. The details of the protocol existing between the Ninf-G Client and Invoke Server are described in Section 3.2
This section describes a sample RPC flow to a server called serverA
via the Invoke Server, IS_SAMPLE
.
(1) A client configuration file that describes that
Invoke Server IS_SAMPLE
is used for RPC to serverA
must be prepared.
(2) The Ninf-G Client requests Invoke Server
IS_SAMPLE
to create a
function/object handle.
(3) The first time IS_SAMPLE
is required to create
a function/object handle, the IS_SAMPLE
process is spawned by
the Ninf-G Client on the same machine.
${NG_DIR}/bin/ng_invoke_server.IS_SAMPLE
is a command
for spawning an IS_SAMPLE
process.
(4) The Ninf-G Client and IS_SAMPLE
communicate using three pipes (stdin, stdout, and stderr).
QUERY_FEATURES
request and reply are performed at first.
(5) When grpc_function_handle_init() is called,
the Ninf-G Client sends JOB_CREATE
request to
IS_SAMPLE
,
followed by the required information
(e.g., the hostname and port number of the remote server),
and JOB_CREATE_END
.
(6) When IS_SAMPLE
receives
JOB_CREATE
request,
IS_SAMPLE
returns "S"
to the Ninf-G Client,
which indicates that the request has been received by
the Invoke Server.
(7) IS_SAMPLE
generates a new Job ID that corresponds
to the Request ID that was transferred with the JOB_CREATE
request, and notifies the Job ID to the Ninf-G Client.
Then, IS_SAMPLE
invokes the remote processes
(Ninf-G Executable) on serverA using its underlying middleware.
(8) The Ninf-G Client waits for the reply from
IS_SAMPLE
,
and notify of Job ID.
When the Ninf-G Client receives the reply and Job ID,
it resumes the execution without waiting for actual job invocation
on serverA.
(9) When the Ninf-G Executable is invoked on serverA,
it connects to the Ninf-G Client using Globus IO.
The connection is used for communication
(e.g., argument transfers from the Ninf-G Client to the Ninf-G Executable)
between the Ninf-G Client and the Ninf-G Executable.
IS_SAMPLE
does nothing for grpc_call().
If the underlying middleware for IS_SAMPLE
returns an error
on remote process invocation, IS_SAMPLE
must notify
the Ninf-G Client that the job invocation has failed.
(10) When grpc_function_handle_destruct() is called, the Ninf-G Client requests the Ninf-G Executable to exit the process. This communication is carried out between the Ninf-G Client and the Ninf-G Executable. The Ninf-G Client does not wait for the Ninf-G Executables to be terminated.
(11) When the Ninf-G Executable exits the process,
the job status managed by IS_SAMPLE
should be changed to
DONE
,
and IS_SAMPLE
notifies the Ninf-G Client of the change
in job status to DONE
.
(12) The Ninf-G Client sends a JOB_DESTROY
request to
IS_SAMPLE
.
(13) IS_SAMPLE
returns "S"
to
the Ninf-G Client when it receives the JOB_DESTROY
request.
(14) IS_SAMPLE
returns DONE
to
the Ninf-G Client
if the state of the corresponding job is DONE
.
Otherwise, IS_SAMPLE
cancels the job and notifies
the Ninf-G Client of the change in status to DONE
when the cancellation is completed and the status of
the job actually becomes DONE
.
(15) When grpc_finalize() is called,
the Ninf-G Client sends an EXIT
request to
IS_SAMPLE
.
(16) IS_SAMPLE
returns "S"
to
the Ninf-G Client when it receives the EXIT
request.
The pipes between IS_SAMPLE
and Ninf-G Client
(stdin, stdout, stderr) are closed after it.
(17) IS_SAMPLE
cancels all jobs and wait
the termination of all jobs, and exit.
(18) When the Ninf-G Client receives an "S"
from
IS_SAMPLE
,
it continues its execution, and does not wait for the termination
of all jobs.
The following figure illustrates the interaction between the Ninf-G Client, Invoke Server, and the Ninf-G Executable.
Figure 1: Interaction between the Ninf-G Client, Invoke Server and the Ninf-G Executable
This section describes a detailed overview of Invoke Server and the protocol existing between a Ninf-G Client and Invoke Server.
Invoke Server is invoked when a Ninf-G Client initializes a function/object handle on the remote server which Ninf-G Client is configured to use with the Invoke Server.
The maximum number of jobs per Invoke Server is limited. If the number of jobs exceeds the limit, a new Invoke Server is invoked.
Invoke Server exits the process if it receives an
EXIT
request
from the Ninf-G Client.
This request is sent when the Ninf-G Client calls grpc_finalize().
Invoke Server also exits the process if it is managing the
maximum number of jobs and all jobs are terminated.
Ninf-G Client does not wait for the termination of Invoke Server
after the Ninf-G Client sends an EXIT
request to
Invoke Server.
If the Ninf-G Client exits abnormally, the pipes will be disconnected. When Invoke Server detects that the pipes have been disconnected, Invoke Server must cancel all jobs and exit the process.
The file names used with Invoke Server must follow the naming convention of "ng_invoke_server" + suffix, where the suffix corresponds to rules for the underlying middleware used for remote process invocation.
A common feature of External Module protocol is described in Section 2.2. A protocol specific to Invoke Server is described in the following sections.
Five Request messages,
JOB_CREATE
, JOB_STATUS
,
JOB_DESTROY
, EXIT
,
and QUERY_FEATURES
are supported.
JOB_CREATE
|
This request is used to create and invoke a new job.
Required information for job invocation is described as a
set of attributes that is transferred along with
a JOB_CREATE
request.
The details of these attributes are described in
Section <IP_ADDRESS>.
JOB_CREATE
is the only request that is described
using multiple lines.
All the other requests can be described with a single line.
A Ninf-G Client transfers a Request ID to Invoke Server. Invoke Server generates a unique Job ID and returns it to the Ninf-G Client. The Job ID is used by the Ninf-G Client to specify the job.
When Invoke Server receives a JOB_CREATE
request,
it must send a Reply message to the Ninf-G Client.
Then, Invoke Server generates a unique Job ID and notifies
the Ninf-G Client of the Job ID.
Finally, Invoke Server requests job invocation on remote servers
via the underlying middleware used with the Invoke Server.
JOB_STATUS
|
This request queries Invoke Server on the status of jobs.
The current version of Ninf-G and prior does not use this
JOB_STATUS
request.
JOB_DESTROY
|
This request is used to terminate and destroy jobs.
Invoke Server cancels all jobs if it receives this request and
the corresponding jobs are not completed.
When Invoke Server confirms that all jobs are cancelled,
it sends DONE
to the Ninf-G Client.
EXIT
|
This request is used to terminate Invoke Server.
If Invoke Server receives this EXIT
request,
it must cancel all outstanding jobs and wait for their termination.
Invoke Server must send a Reply message to a Ninf-G Client if Invoke Server receives a Request message from that Ninf-G Client.
JOB_CREATE
, JOB_DESTROY
, EXIT
The reply to JOB_CREATE
, JOB_DESTROY
,
and EXIT
messages is:
|
where S
is sent in case of Success.
Otherwise, F
is returned, followed by
<Error String>.
JOB_STATUS
The reply to a JOB_STATUS
request is:
|
Where <Status> is denoted as:
<Status> : [PENDING | ACTIVE | DONE | FAILED]
Each status indication indicates the status such that:
PENDING
: the Ninf-G Executable is waiting for invocation.
ACTIVE
: the Ninf-G Executable is already invoked.
DONE
: the Ninf-G Executable is already done.
FAILED
: the Ninf-G Executable exited abnormally.
QUERY_FEATURES
The reply to a QUERY_FEATURES
request is
described in 2.2.3.
Ninf-G Version 5.0.0 Invoke Server has protocol version 2.0.
Following features can be returned.
STAGING_AUTH_NUMBER
If the Invoke Server implements the staging of Simple Auth Number by file, this feature must be returned.
STAGING_COMMUNICATION_PROXY
If the Invoke Server implements the staging of Remote Communication Proxy, this feature must be returned.
A Notify message is used to send an asynchronous message from Invoke Server to a Ninf-G Client. Two types of Notify message are provided.
CREATE_NOTIFY
|
This is used to notify the Ninf-G Client of the Job ID. A Job ID is case sensitive and cannot include invisible characters.
STATS_NOTIFY
|
<Status> : [PENDING | ACTIVE | DONE | FAILED]
This message is used to send notification that the status of a job has been changed.
<String> can be any string,
and the <String> is stored in an output log.
It should be noted that the status of job can be changed from
PENDING
to DONE
.
JOB_CREATE
RequestThis section describes the details of
a JOB_CREATE
Request.
|
Attributes are placed between JOB_CREATE<RET>
and JOB_CREATE_END<RET>
.
Only one attribute can occupy one line and one line must
include one and only one attribute.
Attributes can be placed in any order.
There are two types of attributes, mandatory attributes and
optional attributes. Invoke Server must return an error
if mandatory attributes are not included.
Any unknown optional attributes must be ignored.
The following is a list of attributes supported by Ninf-G.
Some of these attributes are provided for the Globus Toolkit's
Pre-WS GRAM and WS-GRAM.
Any new attribute can be defined using the
Client configuration file <SERVER> section
"invoke_server_option"
attribute.
| name | mandatory | meanings |
|---|---|---|
| hostname | yes | Host name of the server |
| port | yes | Port number |
| jobmanager | no | Job Manager |
| subject | no | Subject of the GRAM |
| client_name | yes | Host name of the Ninf-G Client |
| executable_path | yes | Path of the Ninf-G Executable |
| backend | yes | Backend of the remote function (e.g., MPI) |
| count | yes | Number of Ninf-G Executables |
| staging | yes | A flag indicating if staging is used or not |
| auth_number | no | Simple Auth Number |
| argument | yes | Arguments for the Ninf-G Executable |
| work_directory | no | Working directory of the remote function |
| tmp_dir | no | temporary files directory |
| redirect_enable | yes | A flag indicating redirection of stdout/stderr |
| stdout_file | no | file name of stdout |
| stderr_file | no | file name of stderr |
| communication_proxy_staging | no | stage the Communication Proxy or not |
| communication_proxy_path | no | path of the Communication Proxy |
| environment | no | Environment variables |
| status_polling | yes | Interval of status polling |
| refresh_credential | yes | Interval of credential refresh |
| max_time | no | Maximum execution time |
| max_wall_time | no | Maximum wall clock time |
| max_cpu_time | no | Maximum CPU time |
| queue_name | no | Name of the queue |
| project | no | Name of the project |
| host_count | no | Number of executables per host |
| min_memory | no | Minimum size of requested memory |
| max_memory | no | Maximum size of requested memory |
| rsl_extensions | no | RSL extension |
Detailed description
Host name of the server machine.
The server port number on which the server is listening. The default value is depend on underlying middleware.
The job manager used on the server machine.
The certificate subject of the resource manager contact.
The host name of the client machine.
Absolute path of the Ninf-G Executable. The path represents a remote path if staging is off. Otherwise, the path represents a local path.
The method for launching the Ninf-G Executable is specified as
backend.
The value is NORMAL
,
MPI
, or BLACS
.
If MPI
or BLACS
is specified,
the Ninf-G Executable must be invoked via the mpirun command.
The number of Ninf-G Executables to be invoked.
If the backend is MPI
or BLACS
,
count means the number of nodes.
The value is true if staging is on and Invoke Server must transfer the Ninf-G Executable file from the local machine to the remote machine.
The value to be used as a simple auth number of Ninf-G. The Invoke Server must write this number to file and stage to the server.
In addition, the Invoke Server must add the "--authNumberFile=[remote auth number file]" argument to the Ninf-G Executable to tell the Simple Auth Number.
If this attribute can be treated, the Invoke Server
must tell the Ninf-G Client by sending feature
STAGING_AUTH_NUMBER
on
QUERY_FEATURES
request's reply.
An argument for the Ninf-G Executable is specified using this attribute. This attribute can specify one argument only, and multiple arguments must be specified one by one, by using this attribute for each one. The arguments must be passed to the Ninf-G Executable as arguments.
Example:
argument --connectbackAddress=...
argument --authNumber=...
argument --contextID=...
This attribute specifies the directory in which the Ninf-G Executable is invoked.
The directory in which temporal files are placed.
This attribute is set to true if the stdout/stderr of the Ninf-G Executable has been requested to be transferred to the Ninf-G Client.
If redirect_enable is set to true, this attribute specifies the name of the output file for stdout. Invoke Server must output the stdout to this file. The Ninf-G Client reads this file as an output file and writes the contents of the file to the stdout of the Ninf-G Client.
If redirect_enable is set to true, this attribute specifies the name of the output file of the stderr. Invoke Server must output the stderr to this file. The Ninf-G Client reads this file as an output file and writes the contents of the file to the stderr of the Ninf-G Client.
The value is true if the staging of Remote Communication Proxy is
enabled and Invoke Server must transfer the Remote Communication Proxy
file from the local machine to the server machine.
Staged executable file path on the server machine must be
passed to Ninf-G Executable by
--communicationProxyPath
argument.
This argument must be added by the Invoke Server.
Otherwise, staging of Remote Communication Proxy is not performed.
If this attribute can be treated, the Invoke Server
must tell the Ninf-G Client by sending feature
STAGING_COMMUNICATION_PROXY
on
QUERY_FEATURES
Reply.
This attribute specifies the staged executable file path of Remote Communication Proxy on the local machine. Invoke Server must stage the file specified by this attribute if the staging of Remote Communication Proxy is set to true.
The environment variable for the Ninf-G Executable
is passed using this attribute.
The environment variable and its value are connected by =
.
Only the variable is specified if it does not take a value.
Multiple environment variables must be specified one by one.
Invoke Server may need to check the status of jobs by polling the status of existing jobs. This attribute specifies the interval of the polling. The value is in seconds, and if it is not specified, the default value 0 is passed.
This attribute specifies the interval for refreshing credentials. The value is in seconds, and if it is not specified, the default value 0 is passed.
This attribute specifies the maximum time of the job.
This attributes specifies the maximum wall clock time of the job.
This attribute specifies the maximum cpu time of the job.
This attribute specifies the name of the queue to which the Ninf-G Executable should be submitted.
This attribute specifies the name of the project.
This attribute specifies the number of nodes.
This attribute specifies the minimum requirements for the memory size of the job.
This attribute specifies the maximum memory size of the job.
This attribute can be used to specify the RSL extension which is available for the Globus Toolkit's WS GRAM.
Invoke Server is specified by using the invoke_server attribute in the <SERVER> section.
invoke_server [type]
Type specifies the type of the Invoke Server, such as GT4py or UNICORE.
Invoke Server may require options for its execution. Such options can be specified by an option attribute in the <INVOKE_SERVER> section or by an invoke_server_option attribute in the <SERVER> section.
option [String]
invoke_server_option [String]
Multiple attributes can be specified in the <SERVER> or <INVOKE_SERVER> sections.
Invoke Server must check the status of jobs, and this may be implemented using polling. The polling interval can be specified by the status_polling attribute in the <INVOKE_SERVER> section.
status_polling [interval (seconds)]
The filename of the Invoke Server's execution log can be specified by the invoke_server_log attribute in the <CLIENT> section.
invoke_server_log [filename]
If this attribute is specified, Invoke Server outputs logs to a file with the specified filename and file type of that Invoke Server.
The log_filePath attribute in the <INVOKE_SERVER> section can be used to specify a log file for a specific Invoke Server.
log_filePath [Log file name]
The maximum number of jobs per Invoke Server can be limited by the max_jobs attribute in the <INVOKE_SERVER> section. If the number of requested jobs exceeds this value, the Ninf-G Client invokes a new Invoke Server and requests that Invoke Server to manage the new jobs.
max_jobs [maximum number of jobs]
If Invoke Server is not located in a pre-defined directory, the path attribute in <INVOKE_SERVER> can be used to specify the path of the Invoke Server.
path [path of the Invoke Server]
The Job Timeout function is managed by the Ninf-G Client. Invoke Server is not responsible for the timeout.
Redirect stdout/stderr is implemented using files.
JOB_CREATE
request.
Communication Proxy mediates communications between Ninf-G Executable and Ninf-G Client.
Ninf-G Client communicates with Ninf-G Executables. At this time, if Communication Proxy is not used, direct TCP/IP connection from the Ninf-G Executable to the Ninf-G Client is performed.
If the Communication Proxy is used, following connection is performed.
Ninf-G Executable invokes the Remote Communication Proxy and connects to it.
Remote Communication Proxy connects to the Client Communication Proxy.
Client Communication Proxy connects to the Ninf-G Client.
About connection of 2., any the communication method and Grid Middleware can be used to implement a Communication Proxy.
In communications between Ninf-G Client and Client Communication Proxy, and in communications between Ninf-G Executable and Remote Communication Proxy, a socket is used as Ninf-G protocol while the External Module protocol (request, reply and notify) is communicated with three pipes.
Ninf-G Version 5.0.0 includes the following Communication Proxy:
Following is the flow of connection from Ninf-G Executable to Ninf-G Client via Communication Proxy.
If the Client Communication Proxy is not invoked,
Ninf-G Client invokes the Client Communication Proxy and sends
INITIALIZE
Request to the Client Communication Proxy.
The Client Communication Proxy receives INITIALIZE
Request and initializes itself. Then returns INITIALIZE
Reply to the Ninf-G Client.
The Ninf-G Client sends PREPARE_COMMUNICATION
Request, before requesting Invoke Server to invoke job related to
function/object handle.
The Client Communication Proxy returns the Reply, and prepares communication.
The Client Communication Proxy sends
COMMUNICATION_REPLY
Notify to Ninf-G Client after the
preparation of the communication is completed.
At this time, COMMUNICATION_REPLY
attributes sent to
Ninf-G Client includes the information to connect to
the Client Communication Proxy(We note "CCP connect info" here).
The Ninf-G Client requests to the Invoke Server to invoke a Ninf-G Executable on the server. "CCP connect info" is also send to the Invoke Server.
By the Invoke Server, a Ninf-G Executable on the server is invoked. The Ninf-G Executable invokes a Remote Communication Proxy.
The Ninf-G Executable sends INITIALIZE
Request
to the Remote Communication Proxy with "CCP connect info."
The Ninf-G Executable waits the
INITIALIZE
Reply from the Remote Communication Proxy.
The Remote Communication Proxy prepares the connection from
the Ninf-G Executable, and the address information to connect to the
Remote Communication Proxy is returned to the Ninf-G Executable
by INITIALIZE
Reply.
The Ninf-G Executable connects to the address which was returned from the Remote Communication Proxy.
The Remote Communication Proxy connects to the address which is described in "CCP connect info", by respective way of Communication Proxy defines.
Client Communication Proxy and Remote Communication Proxy is invoked when a Ninf-G Client initializes a function/object handle on the remote server which Ninf-G Client is configured to use with the Communication Proxy.
The maximum number of jobs per Client Communication Proxy is limited. If the number of jobs exceeds the limit, a new Client Communication Proxy is invoked. There may have several connections on one job.
Remote Communication Proxy exits when the Ninf-G Executable is exiting.
Ninf-G Client (Ninf-G Executable) waits the termination of Communication Proxy after the Ninf-G Client sends an EXIT request to Communication Proxy.
The file names used with Communication Proxy must follow the naming convention of "ng_client_communication_proxy" + suffix for Client Communication Proxy, "ng_remote_communication_proxy" + suffix for Remote Communication Proxy , where the suffix corresponds to rules for the underlying middleware used for communication.
A common feature of External Module protocol is described in Section 2.2. A protocol specific to Communication Proxy is described in the following sections.
Four Request messages, INITIALIZE
,
PREPARE_COMMUNICATION
,
EXIT
and QUERY_FEATURES
are supported.
INITIALIZE
|
This request is used to initialize the Communication Proxy after
the invocation. Ninf-G Client and Ninf-G Executable send
this request to Communication Proxy only once.
INITIALIZE
request after the first time
INITIALIZE
causes a failure.
This request allows to take time to initialize and not return
immediately.
This request is a multiple line type request.
INITIALIZE
request attributes are different between
Client Communication Proxy and Remote Communication Proxy.
Following attributes are passed from Ninf-G Client.
Any attributes not shown in the following table can be specified by specifying Ninf-G Client configuration file <CLIENT_COMMUNICATION_PROXY> section option attribute. These attributes are used for any reason for each Communication Proxy.
| name | mandatory | multiple | meanings |
|---|---|---|---|
| listen_port | yes | no | port number of Ninf-G Client |
| buffer_size | yes | no | buffer size |
This specifies the port number on which the Ninf-G Client is listening.
This specifies the buffer size of Client Communication Proxy. The units are in bytes.
Following attributes are passed from Ninf-G Executable.
Any attributes not shown in the following table can be specified by specifying communication_proxy_option attribute in <SERVER> section of Ninf-G Client configuration file. These attributes are used for any reason for each Communication Proxy.
In addition, Remote Communication Proxy receives any attributes which is decided by each Communication Proxy for the following purpose. This attributes may be described by multiple lines.
This information is generated by
COMMUNICATION_REPLY
on Client Communication Proxy.
| name | mandatory | multiple | meanings |
|---|---|---|---|
| hostname | yes | no | hostname of Ninf-G Client |
| buffer_size | yes | no | buffer size |
| tcp_nodelay | yes | no | TCP_NODELAY |
| tcp_connect_retryCount | yes | no | retry count |
| tcp_connect_retryBaseInterval | yes | no | retry base interval |
| tcp_connect_retryIncreaseRatio | yes | no | retry increase ratio |
| tcp_connect_retryRandom | yes | no | random retry |
This specifies the hostname of Ninf-G Client.
This specifies the buffer size of Remote Communication Proxy. The units are in bytes.
This specifies whether or not to set TCP_NODELAY. If the value is true, TCP_NODELAY must be set to all connections to Remote Communication Proxy.
Note: If the TCP/IP is not used for communication between Remote Communication Proxy and Client Communication Proxy, the value is ignored.
This specifies the maximum number of retries for establishing a connection.
This specifies the base interval time for the first retry. The value is in seconds. This value is used as the maximum interval time for the first retry.
This specifies the increase ratio which is used to calculate
the maximum interval time between retries.
The maximum interval time is calculated by multiplying this value
and the maximum interval time for the last retry.
For the first retry, the value of
tcp_connect_retryBaseInterval
is used as
the maximum interval time.
The value is greater than 1.0.
This specifies a flag that specifies whether a random value is used or not for the interval time. If the value is true, the interval time between retries is set randomly between 0.0 seconds to the maximum interval time. If the value is false, the maximum interval time is used as the interval time.
PREPARE_COMMUNICATION
|
This request is used to command the Client Communication Proxy
to prepare communication for Remote Communication Proxy,
when a function handle is creating.
This request is issued before the job invocation request for
Invoke Server. To prepare communication, it will take time.
Thus, report to Ninf-G Client that the communication is
ready, is told not by reply, but of a
COMMUNICATION_REPLY
notify.
This request is only issued to Client Communication Proxy.
This request is a multiple line type request.
Following attributes are passed from Ninf-G Client.
Any attributes not shown in the following table can be specified by specifying Ninf-G Client configuration file <SERVER> section communication_proxy_option attribute. These attributes are used for any reason for each Communication Proxy.
| name | mandatory | multiple | meanings |
|---|---|---|---|
| request_id | yes | no | Request ID |
| tcp_nodelay | yes | no | TCP_NODELAY |
| tcp_connect_retryCount | yes | no | retry count |
| tcp_connect_retryBaseInterval | yes | no | retry base interval |
| tcp_connect_retryIncreaseRatio | yes | no | retry increase ratio |
| tcp_connect_retryRandom | yes | no | random retry |
This specifies the ID to identify the request.
This ID is used by the COMMUNICATION_REPLY
notify,
when the communication become ready.
This specifies whether or not to set TCP_NODELAY. If the value is true, TCP_NODELAY must be set to connections related to this request on the Client Communication Proxy.
Note: If the TCP/IP is not used for communication between Remote Communication Proxy and Client Communication Proxy, the value is ignored.
This specifies the maximum number of retries for establishing a connection.
This specifies the base interval time for the first retry. The value is in seconds. This value is used as the maximum interval time for the first retry.
This specifies the increase ratio which is used to calculate
the maximum interval time between retries.
The maximum interval time is calculated by multiplying this value
and the maximum interval time for the last retry.
For the first retry, the value of
tcp_connect_retryBaseInterval
is used as
the maximum interval time.
The value is greater than 1.0.
This specifies a flag that specifies whether a random value is used or not for the interval time. If the value is true, the interval time between retries is set randomly between 0.0 seconds to the maximum interval time. If the value is false, the maximum interval time is used as the interval time.
EXIT
|
This request is used to exit the Communication Proxy. This request is a one line type request and have no parameter.
Communication Proxy must send a Reply message to a Ninf-G Client (Ninf-G Executable) if Communication Proxy receives a Request message from that Ninf-G Client (Ninf-G Executable).
INITIALIZE
The reply to INITIALIZE
messages is:
|
where S
is sent in case of Success.
Otherwise, F
is returned, followed by
<Error String>.
The reply to INITIALIZE
messages is:
|
where SM
is sent in case of Success.
Otherwise, F
is returned, followed by
<Error String>.
[address-string]
is the address, which the Ninf-G
Executable must connect to.
This address is TCP or the local socket address.
This address may not be Remote Communication Proxy.
The address form is as follows:
ng_tcp://[hostname]:[port-number]
Ninf-G Executable must connect to the hostname of
[hostname]
, and the port number of
[port-number]
by TCP.
ng_local://[path-to-local-socket]
Ninf-G Executable must connect to the
[path-to-local-socket]
by local socket (UNIX domain socket).
PREPARE_COMMUNICATION
, EXIT
The reply to
PREPARE_COMMUNICATION
and EXIT
messages is:
|
where S
is sent in case of Success.
Otherwise, F
is returned, followed by
<Error String>.
QUERY_FEATURES
The reply to a QUERY_FEATURES
request is
described in 2.2.3.
Ninf-G Version 5.0.0 Communication Proxy has protocol version 1.0.
Communication Proxy have no extended features.
A Notify message is used to send an asynchronous message from Communication Proxy to a Ninf-G Client. One type of Notify message is provided.
COMMUNICATION_REPLY
|
This Notify tells the Ninf-G Client that the preparation,
which was requested by PREPARE_COMMUNICATION
Request,
has been completed.
This Notify is only used on Client Communication Proxy.
This Notify is a multiple line type Notify.
Following attributes are passed from Client Communication Proxy.
Any attributes not shown in the following table can be passed, for the following purpose.
This information is used by Remote Communication Proxy to connect to Client Communication Proxy. This information is first passed to Ninf-G Client, then Ninf-G Executable, and finally passed to Remote Communication Proxy. Multiple attributes can be passed. If the preparation of communication failed, this attributes cannot be passed.
| name | mandatory | multiple | meanings |
|---|---|---|---|
| request_id | yes | no | Request ID |
| result | yes | no | result |
| message | no | no | message |
This specifies the Request ID passed by
PREPARE_COMMUNICATION
Request.
This specifies the preparation of communication was successful
or not. S
is returned on success, F
is returned on failure.
This specifies the error cause message. This attribute is only specified on failure case.
Information Service searches and retrieves the Ninf-G Executable information. Ninf-G Executable information is required when a function handle is creating. Information Service is a External Module, which enable to search and retrieve Ninf-G Executable information, without depending on specific Grid Middleware.
Ninf-G Version 5.0.0 includes the following Information Service:
Information Service is invoked when a Ninf-G Client searches a Ninf-G Executable information for new function/object handle.
Ninf-G Client wait for the termination of Information Service after the Ninf-G Client sends an EXIT request to Information Service.
The file names used with Information Service must follow the naming convention of "ng_information_service" + suffix, where the suffix corresponds to rules for the underlying middleware used for information query.
A common feature of External Module protocol is described in Section 2.2. A protocol specific to Information Service is described in the following sections.
Four Request messages,
QUERY_REMOTE_EXECUTABLE_INFORMATION
,
CANCEL_QUERY
,
EXIT
and QUERY_FEATURES
are supported.
|
This Request is used to query the Ninf-G Executable information.
The searched information is returned to Ninf-G Client by
REMOTE_EXECUTABLE_INFORMATION_NOTIFY
Notify.
This Request is a multi line type Request.
Following attributes are passed from Ninf-G Client.
Any attributes not shown in the following table can be specified by specifying Ninf-G Client configuration file <INFORMATION_SOURCE> section option attribute. These attributes are used for any reason for each Information Service.
| name | mandatory | multiple | meanings |
|---|---|---|---|
| hostname | yes | no | hostname |
| classname | yes | no | classname |
| source | yes | yes | source |
This specifies the hostname of query target.
This specifies the classname of query target.
This specifies the source of Ninf-G Executable information. The meaning and expression of source can be defined by respective Information Service. The Information Service must search the information from the specified sources. This attribute can specify one source only, and multiple sources can be specified one by one.
|
This request is used to cancel the ongoing query of the
Ninf-G Executable information.
The argument <Query ID>
is the ID issued by
QUERY_REMOTE_EXECUTABLE_INFORMATION Reply.
This Request is a one line type Request.
|
This request is used to exit the Information Service. This request is a one line type request and have no parameter.
Information Service must send a Reply message to a Ninf-G Client if Information Service receives a Request message from that Ninf-G Client.
QUERY_REMOTE_EXECUTABLE_INFORMATION
The reply to QUERY_REMOTE_EXECUTABLE_INFORMATION
messages is:
|
where S
is sent in case of Success.
Otherwise, F
is returned, followed by
<Error String>.
Query ID is the ID to identify the query. A Query ID is case sensitive and cannot include invisible characters.
CANCEL_QUERY
, EXIT
The reply to CANCEL_QUERY
and EXIT
messages is:
|
where S
is sent in case of Success.
Otherwise, F
is returned, followed by
<Error String>.
QUERY_FEATURES
The reply to a QUERY_FEATURES
request is
described in 2.2.3.
Ninf-G Version 5.0.0 Information Service has protocol version 1.0.
Information Service have no extended features.
A Notify message is used to send an asynchronous message from Information Service to a Ninf-G Client. One type of Notify message are provided.
|
This Notify is used to return the information, queried in advance from the Ninf-G Client. The returned query result is success or failure, and if the result is success, XML form of information is returned. This Notify is a multi line type Notify.
The XML information, that must be returned to Ninf-G Client is as follows:
rei=http://ninf.apgrid.org/2006/12/NinfGRemoteInformation
rci=http://ninf.apgrid.org/2006/12/RemoteClassInformation
<rei:RemoteExecutableInformation>
.
<rei:hostName>
text in
<rei:RemoteExecutableInformation>
must be hostname of specified query target.
"name"
attribute of <rci:class>
in
<rei:RemoteExecutableInformation>
must be classname of specified query target.
This XML document is written in NRF file, which is generated when the Ninf-G Executable is compiled.
Following attributes are passed from Information Service.
| name | mandatory | multiple | meanings |
|---|---|---|---|
| query_id | yes | no | Query ID |
| result | yes | no | Query result |
| remote_executable_information | no | yes | information |
| error_message | no | no | error message |
This specifies the query ID, which is generated by QUERY_REMOTE_EXECUTABLE_INFORMATION Reply.
This specifies the result of the query.
If the query is successful, S
is returned,
otherwise, F
is returned.
This specifies the Remote Executable Information. This information is XML document, which have multiple lines. This attribute can specify one line of XML document only, and multiple lines must be specified one by one, by using this attribute for each one. The attribute value cannot include a return character code.
This attribute is only specified if the query is successful.
This specifies the error message, when the query fail.
This attribute is only specified if the query fail.


confirm
see product
method
put product
confirm + method
destroy product
remote
see product (remote)
confirm + remote
post product
method + remote
confirm + method + remote (delete)
delete product
confirm + disable-with
remote (get)
confirm + disable-with + remote


BlocklyProp
> web-based visual programming editor for spin
Blocks
Propeller C
XML
Compile
Load into Ram
Load into Eeprom
Serial console
Discard
Save XML
Load XML
×
Modal title
Result
×
Console
×
Project setup
Board type
Activity board
Board of Education
Propeller C3
Demo board
Proto board
Quickstart
Scribbler 2
Other
Memory model
Block types
Serial
Serial terminal
Debug LCD


--- ---
Calling this procedure from the form's OnActivate event will resize the form in proportion to the screen resolution – I do my programming on resolution 1280×768 hence the constants – once the form height and width has been calculated it can then be centred.
Note – form should be set to autoresize and
AutoScroll := False
at least while being re-calculated. Also
the font size for the form should be (probably) 12 for the font to be resized
downwards for 800×600 – all controls should be set to
ParentFont := True
so they will resize.
While this works exactly for the old screen resolutions which were all more
or less in proportion there is nothing which will resize screens properly
for the newer stretched screens, eg. for 1280×960 and 1280×1024.
The min ratio calculated is scrx / screenx = 1
so the form
stays with original measurements.
uses math,windows; const screenx = 1280; screeny = 768; procedure tform1.autosizeall ; var scrx,scry, k:integer ; ratio:double; begin scrx:= GetSystemMetrics(SM_CXSCREEN); {finds screen resolution x value} scry:= (GetSystemMetrics(SM_CYSCREEN)); {finds screen resolution y value} ratio:=min(scrx/screenx,scry/screeny); {takes the smaller ratio and makes sure you dont make the window too big for the screen} scaleby(trunc(ratio*100),100); {scales all controls and attempts to place them in the correct position} {to centre the form on the screen} form1.Left:=centreleft(form1.width); form1.Top:=centretop(form1.Height) ; end;
This code refers to two functions: centreleft and centretop. These are defined as follows:
function centreleft(fw:integer):integer; {calculates the form.left} var smcx:integer; begin smcx:=GetSystemMetrics(SM_CXSCREEN); centreleft:=(smcx-fw) div 2; end; function centretop(fh:integer):integer; {calculates the form.top} var smcy:integer; begin smcy:=GetSystemMetrics(SM_CYSCREEN); centtop:=(smcy-fh) div 2; end;


Uza Cloud Storage
Upload article
Currency
USD
EUR
Category
Men
Women
Kids
Electronic
Craft
Other
Type
Clothing
Shoes & Bags
Watches & Accessories
Perfumes & Beauty
Other
Seller
Amazon
Ebay
Priceminister
Zalando
Discount
Uza
Other
Add colors
Size
XXS
XS
S
M
L
XL
XXL
34
36
38
40
42
44
46
48
50
52
54
56
58
60
62
64


- being in Chiang Mai, Thailand
- swimming almost every day
- climbing almost every day (although the natural Crazy Horse crag has been shutdown by the Government)
- working on the management system of the University of Saint Joseph, one of my clients;
- building a new management system for schools, hoping to be helping schools in Macau with a better system than the ones they are currently using;
- eating awesome Thai food
- building an Alfred workflow to easily record English/Cantonese words equivalence because it's easy to forget Cantonese tones (alfred-canto)
- reading psychology, philosophy, biographies, and a bit of fiction
- writing fiction at sleeplessmind.info
- learning Portuguese
- reviewing Cantonese
- drinking beers


Home
Sign Up
Sign up and join us
First Name:
Last Name:
Email:
Home Town:
Major:
Sign Up
Sign up and see my update ASAP


Home
Some sites, like Twitter, have a character limit, forcing you to split long messages into chunks. This tool splits the message into individual ones of specified length.
Size of each message (number of characters):
Split message


£{{eachListing.price}}/ month Commute Time
{{eachListing.address}}
Oakwood Station - 0.3 miles away
Added 3 Days Ago
Oakwood Station - 0.3 miles away
Listed by
{{shortlistProperty.agent_name}}
{{shortlistProperty.agent_address}}
{{shortlistProperty.agent_phone}}
Added 3 Days Ago


ThreadPoolExecutor is the recommended way to perform multithreading in Python. Multithreading is a way to speed up your application and is suitable for I/O bound tasks such as HTTP requests, database operations, etc.
Introduction
The simplest way to show how to use ThreadPoolExecutor is by example:
The application above will print the statement “I’m running in a thread: “ with the number 1 to 10, which will most probably be out of order.
Code Explanation
First, we created a ThreadPoolExecutor with 2 threads. Then, we submit 10 tasks to the ThreadPoolExecutor with a for-in loop, and in turn receive Future objects which we store in a list. We then loop through the list of futures using the as_completed() function, which allows us to receive futures that complete first instead of going sequentially through the futures list. Finally, we obtain the result of the task() function by calling future.result() and print the outcome.
Handling Exceptions
The example above was super simple, but what if we need to do something more complicated like firing concurrent HTTP requests. There is a possibility that the code may hit Exceptions during runtime due to uncontrollable reasons i.e. network issues, configuration issues. We can put a try-except block to handle Exceptions, but what if we want to cancel all submitted tasks when a future fails?
Shutdown
There is a built in function for ThreadPoolExecutor called shutdown().
In Python 3.7 and 3.8, shutdown() only stops the ThreadPoolExecutor from accepting new tasks. This means that if we submit all our tasks in one go at the beginning, and mid-way through a task fails which causes the future to return an Exception, other pending tasks that have not started running and are still in the executor’s job queue will NOT be cancelled.
Fortunately, it was revamped in Python 3.9 to allow users to cancel pending tasks in the executor’s job queue.
Python 3.7 and 3.8
At the time of writing this blog post I was using Python 3.7.10 and Python 3.8.5.
In Python 3.7 and 3.8, shutdown() only accepts one boolean parameter, wait. When wait = True, Python will wait until all submitted tasks have finished running before shutting down the ThreadPoolExecutor.
When wait = False, it will still behave in the same way. The only difference is that the call to executor.shutdown() will not block. The executor will continue running all pending tasks, but will not accept new tasks and will completely shut down after all tasks are ran. Meanwhile, the main thread continues with our script’s main execution flow.
In the code example above, a ValueError exception will be raised when num = 5. After hitting the ValueError exception, the script will call shutdown().
When wait = True, Python will wait for all futures after num = 5 to complete and print it out (almost) all at once.
Since wait = True, after handling the ValueError exception, the main thread will wait for all tasks in the job queue to complete, before returning to the for-in loop to receive completed futures from as_completed() and to print out the results. Notice that the results printed after the ValueError exception are printed at approximately the same time.
Meanwhile, when wait = False, Python will continue with the main thread’s execution flow.
Since wait = False, after handling the ValueError exception, the main thread immediately continues with the script’s execution flow, which is to wait and receive completed futures from as_completed() and to print out the results. Notice that the results printed after the ValueError exception are printed as each future completes.
At the time of writing this blog post, I was using Python 3.9.5.
In Python 3.9, an additional boolean parameter, cancel_futures, was added to shutdown(). This allows us to cancel pending futures in the queue that have not started running if any future fails mid-way through. However, there is a catch. If you use the as_completed() function, the script will be stuck indefinitely after calling executor.shutdown() because as_completed() is not triggered when a future is in the CANCELLED state.
As you can see here, as_completed() only returns a future if it is in the CANCELLED_AND_NOTIFIED or FINISHED state. Meanwhile, executor.shutdown() only cancels the future but does not change its state to CANCELLED_AND_NOTIFIED.
To confirm it, we can run this block of code below.
We are printing the states of all the futures every time we enter the for-in loop. The results of the block of code above is as shown below:
We can see that after the ValueError exception is handled, the last two futures changes state from PENDING to CANCELLED. The script will then be stuck because as_completed() never returns the remaining two futures.
What To Do
The way I fixed this is to scrap using the as_completed() function. Although it is the recommended way to loop through a list of futures, it’s useless if it causes the script to hang.
Now, we are going through the list of futures sequentially. We are also checking if the future is in CANCELLED state and if it is, we proceed to the next future. We have successfully avoided the never-ending as_completed() function when .shutdown(cancel_futures=True) is called.
The output of the code above will look like:
Bonus: I Want To Cancel Futures On Shutdown in Python 3.7 and 3.8
With a bit of knowledge of object-oriented programming, we can! Simply inherit the ThreadPoolExecutor class and add a new method (in case we still want the original shutdown()) with Python 3.9’s version of shutdown().


{% if user.permissions.can_add_repo %}
{% endif %}
{% trans "Name" %}
{% trans "Size" %}
{% trans "Last Update" %}
{% trans "Shared By" %}
{% trans "No library is sharing to this group" %}
{% blocktrans %}You can share libraries by clicking the "New Library" button above or the "Share" icon on your libraries list.{% endblocktrans %}
{% trans "Libraries shared as writable can be downloaded and synced by other group members. Read only libraries can only be downloaded, updates by others will not be uploaded." %}
{% include "js/dir-view.html" %}
{% endblock %}
{% block extra_script %}
{% include "js/lib-op-popups.html" %}
{% if debug %}
{% else %}
{% endif %}
{% endblock %}


|
|
| Map () |
| | Empty constructor.
|
| |
| | Map (const Map< K, V > &other) |
| | Copy constructor. More...
|
| |
|
| ~Map () |
| | Destructor.
|
| |
| V & | operator[] (const K &key) |
| | Returns value with specified key. More...
|
| |
| K | operator() (const V &value) const |
| | Same as key_of. More...
|
| |
| bool | operator== (const Map< K, V > &other) const |
| | Same as equals. More...
|
| |
| bool | operator!= (const Map< K, V > &other) const |
| | Same as nequals. More...
|
| |
| int | size () const |
| | Returns the number of values in the Map. More...
|
| |
| Array< K > | keys () const |
| | Returns an Array with all keys. More...
|
| |
| Array< V > | values () const |
| | Returns an Array with all values. More...
|
| |
| Array< V > | values (const Array< K > keys) const |
| | Returns an Array with all values in the same order as the given corresponding keys. More...
|
| |
| Array< std::pair< K, V > > | keyValuePairs () const |
| | Returns an Array with all key-value pairs. More...
|
| |
| Array< std::pair< K, V > > | keyValuePairs (const Array< K > keys) const |
| | Returns an Array with all key-value pairs in the same order as the given corresponding keys. More...
|
| |
| bool | equals (const Map< K, V > &other) const |
| | Compares the contents of two Maps for being equal. More...
|
| |
| bool | nequals (const Map< K, V > &other) const |
| | Compares the contents of two Maps for being not equal. More...
|
| |
| K | keyOf (const V &value) const |
| | Returns key of specified value. More...
|
| |
| V | valueOf (const K &key) const |
| | Returns value of specified key. More...
|
| |
| bool | hasKey (const K &key) const |
| | Checks for existence of a key. More...
|
| |
| bool | hasAnyKey (const Array< K > &keys) const |
| | Checks for existence of a key within an Array of keys. More...
|
| |
| bool | hasAnyKey (const K keys[], const int count) const |
| | Checks for existence of a key within an Array of keys. More...
|
| |
| bool | hasAllKeys (const Array< K > &keys) const |
| | Checks for existence of all keys. More...
|
| |
| bool | hasAllKeys (const K keys[], const int count) const |
| | Checks for existence of all keys. More...
|
| |
| bool | hasValue (const V &value) const |
| | Checks for existence of a value. More...
|
| |
| bool | hasAnyValue (const Array< V > &values) const |
| | Checks for existence of a values in an Array of values. More...
|
| |
| bool | hasAnyValue (const V values[], const int count) const |
| | Checks for existence of a values in an Array of values. More...
|
| |
| bool | hasAllValues (const Array< V > &values) const |
| | Checks for existence of all values. More...
|
| |
| bool | hasAllValues (const V values[], const int count) const |
| | Checks for existence of all values. More...
|
| |
| void | insert (const K &key, const V &value) |
| | Adds a new pair of key and value into the Map. More...
|
| |
| void | insert (const Map< K, V > &other) |
| | Adds all pairs of keys and values from another Map into this one. More...
|
| |
| void | inject (const Map< K, V > &other) |
| | Adds all pairs of keys and values from another Map into this one. More...
|
| |
| bool | removeKey (const K &key) |
| | Removes a pair of key and value specified by a key. More...
|
| |
| int | removeKeys (const Array< K > &keys) |
| | Removes all pairs of key and value specified by an Array of keys. More...
|
| |
| bool | removeValue (const V &value) |
| | Removes a pair of key and value specified by a value. More...
|
| |
| int | removeValues (const Array< V > &values) |
| | Removes all pairs of key and value specified by an Array of values. More...
|
| |
| K | random (V *value=NULL) const |
| | Gets a random element in Map. More...
|
| |
| Map< K, V > | random (int count) const |
| | Gets a Map of random elements selected from this one. More...
|
| |
| K | removeRandom (V *value=NULL) |
| | Gets a random element in Map and removes it. More...
|
| |
| Map< K, V > | removeRandom (int count) |
| | Gets a Map of random elements selected from this one and removes them. More...
|
| |
| Map< K, V > | findAll (bool(*conditionFunction)(K const &, V const &)) const |
| | Finds and returns new Map with entries that match the condition. More...
|
| |
| bool | matchesAny (bool(*conditionFunction)(K const &, V const &)) const |
| | Checks if at least one entry matches the condition. More...
|
| |
| bool | matchesAll (bool(*conditionFunction)(K const &, V const &)) const |
| | Checks if all entries match the condition. More...
|
| |
| template<typename L , typename S > |
| Map< L, S > | cast () const |
| | Returns a new Map with all keys and values cast into the type L and S. More...
|
| |
| template<typename L , typename S > |
| Map< L, S > | dynamicCast (bool includeNulls=false) const |
| | Returns a new Map with all keys and values dynamically cast into the type L and S. More...
|
| |
| template<typename L , typename S > |
| Map< L, S > | dynamicCastKeys () const |
| | Returns a new Map with all keys and values dynamically cast into the type L and non-dynamically into S. More...
|
| |
| template<typename L , typename S > |
| Map< L, S > | dynamicCastValues (bool includeNulls=false) const |
| | Returns a new Map with all keys and values cast into the type L and dynamically into S. More...
|
| |
| V | tryGet (K key, V defaultValue) const |
| | Finds and returns value stored at key. In case no value is found, returns the given default value. More...
|
| |
| Map< K, V > & | operator+= (const Map< K, V > &other) |
| | Same as insert. More...
|
| |
| Map< K, V > | operator+ (const Map< K, V > &other) const |
| | Merges two Mapss. More...
|
| |
template<typename K, typename V>
class hltypes::Map< K, V >
Encapsulates std::map and adds high level methods.


Chapter 2 Topics:
Bold and Strong
'b' tag is used to create a 'b' element, which represents bold text in an HTML document
'strong' tag is used to create a 'strong' element, which represents strong text in an HTML document
Italic and Emphasis
'i' tag is used to create a 'i' element, which represents italic text in an HTML document
'em' tag is used to create a 'em' element, which represents emphasis text in an HTML document
HTML Abbreviation:
HTML Hypertext Markup Language
Citations
A Brief History of Time by Stephen Hawking has sold over ten million copies worldwide
Definitions
A black hole is a region of space from which nothing, not even light, can escape
Insert and Delete
It was the worst best idea she had ever had.
Strikethrough
Laptop computer:
Was $995
Now only $375
Quotations
Did you ever stop to think, and forget to start again?
As A.A. Milne said, Some people talk to animals. Not many listen though. That's the problem.
Quotations
Superscript and Subscript
On the 24th of November you will learn about E=MCs2.
The amount of CO2 in the atmosphere grew by 2pm in 20091 .
Address
<EMAIL_ADDRESS>Plot 245/2 M, Block 6 PECHS, Karachi, Sindh 75100, Pakistan


{% extends 'base.html' %} {% load static %} {% block content %}
Feel free to loop about everything happening in your neighborhood.


Tests DOMAgent.setOuterHTML protocol method against an XHTML document.
WebKit is used by Safari, Dashboard, etc.
There are many ways to get involved. You can:


The process during parsing of replacing syntactic sugar with with another form.
For example, the expression a + b is desugared to Add(a,b).


Name
Dependents
Discount
Paycheck Cost
Paycheck Total
Annual Cost
Annual Total
{{employee.name}}
{{employee.numberOfDependents}}
{{employee.discountPercentage}}%
${{employee.paycheckCostTotal|number:2}}
${{employee.paycheckTotal|number:2}}
${{employee.annualCostTotal|number:2}}
${{employee.annualTotal|number:2}}
Amount - ((Cost of Benefits - Dependents * Cost of Dependents) * Discount) = Total
${{employee.annualAmount|number:2}} - ((${{employee.annualCostOfBenefits|number:2}} - {{employee.numberOfDependents}} * $500.00) * {{employee.discountPercentage}}%) = ${{employee.annualTotal|number:2}}
${{employee.paycheckAmount|number:2}} - ((${{employee.paycheckCostOfBenefits|number:2}} - {{employee.numberOfDependents}} * $500.00) * {{employee.discountPercentage}}%) = ${{employee.paycheckTotal|number:2}}


Blogging to Learn and Reflect
Blogging did not come easily for me. It's like flossing. You kow you should do it, and you are better for having done it, but it just does not flow like coding does. A couple of years ago, I signed up for an account with WordPress, and went through the process of customizing the look of the site, but I could not get myself to write anything. I felt that I would be judged by what I wrote and so any topic I chose, I had to know as much as anyone and do a really great job on it.
For a while I tried posting things I learned to Twitter. I still do that, but I realize that Twitter is more like a party where people are making small talk, not delving in to heavy technical or personal topics.
Now I signed up for Dev Bootcamp, and I have to blog. And I cannot take forever trying to learn all I can about a topic so I am the expert. We are making two posts almost every week, and there just isn't the time to research a topic to expert level. Some post are reflective where we cannot just research, we have to look inside ourselves for the content.
The upside of all this pressure to blog is that I no longer fear blogging. I can research a topic enough to write about it. I can reflect on the personal post topics and express what I am thinking. I do not know that I will blog at the same rate after Dev Bootcamp, but I know that I can blog, and the research needed for a blog post is a great way to start exploring a new technology.
A side of this blogging experience is the creation of this blog site. It initially was quite crude, but has evloved in to something much nicer as my skills have improved. I have learned to look at the blogs of others and for things I like, see how they made that work and then add it to my site. I am not sure how long I want to keep doing this, as I am feeling the urge to have comments, and more managed post control.


I read about 1,4b and decided to give it a try. While I was waiting for it to arrive, I read as much as possible. During this period I very seriously considered dumping it down the toilet and not even bothering to get involved with what I have learned to be a very addictive liquid. But, in the end, curiousity won, and here is my recap of what happened this morning.
The bottle of clear liquid arrived and I immediately dipped a finger in the surprisingly thick and oily(?) liquid. It tasted very bitter, so I thought of what I might mix it with. I was almost sure at the time that I felt some effects from just the small amount that I had tasted but dismissed it as excitement/anxiety.
The next day came and I decided to start small;
T=0; 1.2ml mixed in a shot of Orange juice.
T+10min; Legs feel a bit wobbly but I just got done with my workout so it's possible to attribute to that.
T+15min; Definitely feeling giddy, warm, and goofy (kind of laughing to myself over nothing) Don't care one bit about the 9 to 5 stuff that I was worrying about fifteen minutes ago. I want to take more but force myself to wait til at least 45min. have passed.
T+25min; This thing is starting to ramp up a bit, almost want to be nauseous, getting dizzier.
T+35min; *Very* dizzy at this point, feel like I might vomit, consider eating something to combat the nausea, force myself to continue on with my after work routine, I'd like to lie down but I am not going to do that until the effects have lightened up a little.

T+50min; Feel better having eaten something, still outrageously dizzy; Aside from the nausea and extreme dizziness, I kind of like the body-high: legs feel wobbly and kind of vibrating sensation within my muscles, spreading warmth, very relaxed.
T+60min; The effects seem to be winding down ever so slightly, so now I feel comfortable going to bed. I am sooooo grateful that I did not take any more when I considered doing so at ten minutes. I feel that, had I taken any more at that time, unrousable sleep would've surely ensued. I had originally considered taking 3ml. Good thing I started with just 1.2ml.
At this point you must think that I didn't measure my dosage right...BUT I measured it with a 15ml graduated centrifuge tube with 0.2ml increments, I am 100% sure of my measurement. It was only 1.2 milliliters! Maybe I'm just hypersensitive to this stuff!? Or maybe it was a strong batch?! This is a great reinforcment to the notion of starting small with unknowns, then take what you think is small and divide it in half (so maybe I did really feel something from the small amount that I tasted the previous day- WOW potent stuff!).
As far as the famous four-hour dopamine release, well, I woke up *Exactly* four hours after T=0 but went immediately back to sleep for several hours. If it happened, it wasn't significant enough to notice. It is now almost 18hrs later, and I am still kind of *weak-kneed*. I don't know if I will do this again. Maybe try 0.5ml next time.
Experience Reports are the writings and opinions of the individual authors who submit them.
Some of the activities described are dangerous and/or illegal and none are recommended by Erowid.


GLAM (GL And Markup) is a declarative language for creating 3D content for browsers. It renders with WebGL, using the graphics power of Three.js. GLAM adds behaviors, interaction and lots of easy to use features on top of Three.js, but most importantly, it defines a markup language and set of stylesheet extensions that make 3D programming a snap. With GLAM, 3D authoring is like any other web authoring. To make 3D, you create elements, set their attributes, add event listeners, and define styles. Just like DOM used to make! Content is easy to animate: keyframes and tweens can be defined in a compact set of markup tags, or as standard CSS3 animations or transitions. GLAM is also fully extensible: to add custom behavior, write JavaScript event handlers. If you want fancy shading written in GLSL, simply specify your vertex and fragment shaders as properties of the object's style. GLAM was created by Tony Parisi, the guy who made the Virtual Reality Markup Language (VRML), 20 years before anybody knew they needed it. Since then, Tony's learned a few more things about graphics, web browsers have grown up, and the world has caught up with his vision. GLAM is still quite young. We're adding features and demos at a rapid clip, and we are also looking closely at related technologies such as Web Components as they come of age. We'd love your feedback and contributions!
WebGL is ubiquitous. With the release of iOS8, WebGL now runs on all major desktop and mobile browsers, across all devices. That's 3 billion seats ready for connected 3D applications, everywhere, powered by JavaScript. This is an incredible opportunity to change the face of computing. The last few years have seen an explosion of interest in building WebGL. But there is a huge skill gap. 3D is inherently hard, yes; we have that extra dimension to worry about, plus cameras, shaders, skinned animations, etc... But there is no reason to make 3D harder than it has to be. For the simple 3D stuff, there should be a simple way to do it, with an approach that is familiar to the millions of web developers ready to try something new. Until GLAM, this didn't exist. GLAM is here to make your 3D job easier, so you can focus on the fun part: building a killer 3D web app.
To add GLAM to your application, simply include either the debug or minified version of the library: <script src="pathtoglam/glam.js"> </script> OR <script src="pathtoglamlib/glam.min.js"> </script> ... and then you can start adding 3D tags to your page. To see what those tags look like, read the Getting Started Tutorial (link)
Right now, authoring GLAM requires a text editor. Someday, maybe, we'll build an interactive tool for authoring, or at least a syntax assisted in browser editor a la JSFiddle. To test, you will most likely need a web server ... so that you can see your texture maps and shaders. Launching HTML files from your Finder/Explorer usually results in the browser yakking about crossorigin restrictions. How Can I Participate? GLAM is new. We're just getting started, and we need your help! We are looking for help with code, content and documentation. Check out the Github repo and examples (links here) and join the GLAM revolution! CAN YOU DIG IT?


Answer all questions in a plain text file
named questions7.txt
.
At the top of your plain text file, include your name, student ID, and lab section.
fsm.t
should be a separate .t file.
Do not add a .txt extension.
Your source code should be a plain .t file.
Use scp
to retrieve this file from tux.
Failure to do so will result in a 0.
Suppose you're working for some large unnamed online retail company, let's call them Nile. Everyone has agreed that it would be a good idea to weigh all the boxes that make up an order. Your task is to develop the system that gathers the data. After considering it for a while, you have settled on the following:
The normal procedure for the operator is to start processing an order by scanning the order's barcode. Then for each package in the order, the operator scans the package barcode, and pushes the weight button. Once all the packages are weighed, the operator scans the order barcode again to close the order. At each of those steps, if the operator has taken the correct action, a green light is shown. But if the operator presents one of the inputs out of order, the red light is shown.
So the question is how do we know which light to illuminate? The answer comes down to knowing how we got to our current situation and what input we receive. If we're in the situation where we're currently processing and order and the last thing we got was a package barcode, then getting a weight should result in a green light. On the other hand if the last thing we got was a weight, then another weight should result in a red light.
In a state machine the state summarizes the past and tells us what our current situation is. Then the current state and the new input tell us what to do next. In this situation, the what to do next is what light to turn on and what new state to go to. Of course, we need to account for all the combinations of state and input. One way to express this is with a table such as:
| 0 | 1 | 2 | |
|---|---|---|---|
| O | 1/G | 0/G | 0/R |
| P | 0/R | 2/G | 1/R |
| W | 0/R | 1/R | 1/G |
In this particular case, it so happens that we have three states and three inputs, but they're not always the same. We can describe the states as follows:
Similarly, the inputs are:
In the cells of the table, each entry contains a number and a letter. The number gives the new state and the letter is which color of light to show. For example, if the machine is in state 1 and gets an O input, then the machine changes to state 0 and shows the green light. These changes in state are called transitions. This particular transition represents the operator scanning the order barcode after processing all the packages to close out the order.
Another common way of illustrating a state machine is a diagram where the states are shown as circles and the transitions are shown as arrows. The machine discussed here can be illustrated as follows:
Now, let's turn to how to implement a state machine in Tranquility code. One of the easiest ways to implement a state machine is to define a function for each input. Inside the function, a series of if statements test the current state and do the state updates. In terms of the table shown above, this function implements one row of the table. Based on that table, a function for handling the weight would look like:
fun proc_weight() { if .state == 0 { state : 0 do_red() } else if .state == 1 { state : 1 do_red() } else if .state == 2 { state : 1 do_green() } }
In some cases, the state change in the if statement is redundant as the machine actually stays in the same state. Those assignments could safely be omitted. Also note that the state variable needs to be declared globally so that it is shared among all of the functions.
Your task is to complete the implementation of this state machine. Use a button for each of the three inputs, and use a text area to report which light is on.
Put the URL to your web page for this project as an answer. The webpage should be named fsm.html.
Submit on BBLearn
questions7.txt : A plain text file with your website URL (25pts)
fsm.t : Your Tranquility source code (75pts)
Webpage on tux
fsm.html : Your resulting webpage you make