|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object java.lang.Thread coins.driver.CompileThread
A compiler thread.
COINS Compiler Driver API executes compile steps of one compile unit by one
thread. If the option -conis:compile-paralle is specified, all the threads
are concurrently executed.
The compiler modules executed in the thread can get the thread object by a
method Thread.currentThread(), whose return value can be narrowed to this
class.
Some services are provided by the thread object:
| Nested Class Summary | |
(package private) class |
CompileThread.Assembler
|
(package private) class |
CompileThread.Compiler
|
(package private) class |
CompileThread.Linker
|
(package private) class |
CompileThread.PassGroup
|
(package private) class |
CompileThread.Preprocessor
|
| Field Summary | |
(package private) StopWatch |
fClock
|
(package private) CompilerImplementation |
fImplementation
|
(package private) IoRoot |
fIoRoot
|
(package private) boolean |
fIsLinkerThread
|
(package private) java.lang.String |
fSourceFileName
|
(package private) CompileSpecification |
fSpec
|
(package private) CompileStatus |
fStatus
|
(package private) TemporaryFileManager |
fTemporaryFileManager
|
(package private) java.util.Map |
fThreadLocalVariables
|
| Fields inherited from class java.lang.Thread |
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY |
| Constructor Summary | |
(package private) |
CompileThread(java.lang.String pSourceFileName,
CompileSpecification pSpec,
TemporaryFileManager pTemporaryFileManager,
CompilerImplementation pImplementation,
CompileStatus pStatus,
boolean pIsLinkerThread)
|
| Method Summary | |
java.io.File |
createTemporaryFile()
Returns a File object representing a newly created temporary file. |
long |
elapsedTime()
Returns an elapsed mili-seconds since this thread was started. |
int |
getExitStatus()
Gets the current value of the exit status. |
IoRoot |
getIoRoot()
Gets an IoRoot object. |
java.lang.Object |
getThreadLocalVariableValue(java.lang.String varName)
Gets the value of a thread local variable. |
boolean |
isDefinedThreadLocalVariable(java.lang.String varName)
Tests if a thread local variable is defined or not. |
java.lang.Object |
removeThreadLocalVariable(java.lang.String varName)
Removes a thread local variable. |
void |
run()
|
void |
setABEND()
Sets a value representing `abnormal end' to the exit status. |
void |
setExitStatus(int s)
Sets a value to the exit status of this compilation. |
java.lang.Object |
setThreadLocalVariableValue(java.lang.String varName,
java.lang.Object value)
Sets a value to a thread local variable. |
void |
storeToFile(java.io.InputStream in,
java.io.File dest)
Reads data from an InputStream and stores them to a file. |
| Methods inherited from class java.lang.Thread |
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getContextClassLoader, getName, getPriority, getThreadGroup, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setName, setPriority, sleep, sleep, start, stop, stop, suspend, toString, yield |
| Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
| Field Detail |
java.lang.String fSourceFileName
boolean fIsLinkerThread
TemporaryFileManager fTemporaryFileManager
CompilerImplementation fImplementation
CompileSpecification fSpec
IoRoot fIoRoot
CompileStatus fStatus
java.util.Map fThreadLocalVariables
StopWatch fClock
| Constructor Detail |
CompileThread(java.lang.String pSourceFileName, CompileSpecification pSpec, TemporaryFileManager pTemporaryFileManager, CompilerImplementation pImplementation, CompileStatus pStatus, boolean pIsLinkerThread)
| Method Detail |
public IoRoot getIoRoot()
public int getExitStatus()
public void setABEND()
public void setExitStatus(int s)
s
- the status valuepublic boolean isDefinedThreadLocalVariable(java.lang.String varName)
varName
- the name of the variable
public java.lang.Object getThreadLocalVariableValue(java.lang.String varName)
varName
- the name of the variable.
public java.lang.Object setThreadLocalVariableValue(java.lang.String varName, java.lang.Object value)
varName
- the name of the variable
public java.lang.Object removeThreadLocalVariable(java.lang.String varName)
varName
- the name of the variable
public long elapsedTime()
public java.io.File createTemporaryFile() throws java.io.IOException
java.io.IOException
- if temporary file creation fails.public void storeToFile(java.io.InputStream in, java.io.File dest) throws java.io.IOException
in
- the source InputStreamdest
- the destination File
java.io.IOException
- if storing data to a file failspublic void run()
|
||||||||||
| PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
| SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |


Posted by: Bahati
The statement released last night also shows that 190 cases have been found out of 16811 sample tests, 359 have recovered while 16 patients are critically ill. The statement released last night also shows that 190 cases have been found, 359 have recovered while 16 patients are critically ill. The majority of new cases were found in Kigali: 54, Karongi: 34, Kayonza: 17, Nyamagabe: 16 and Nyagatare: 14. Rwanda confirmed the first COVID-19 patient on 14th March 2020. Since then, 16 811 people have been tested positive out of 926 187 sample tests of whom 10272 have recovered, 3597 are active cases while 226 have succumbed to the virus.
Coronavirus symptoms include coughing, flu, and difficulty in breathing. The virus is said to be transmitted through the mucous membranes of the respiratory tract. Rwandans are urged to adhere to COVID-19 health guidelines, washing hands frequently using soaps and safe water, wearing face masks and respecting social distancing.


Seeing this means your code was successfully deployed
Watch the tutorial | Source Code | Follow us on Twitter


--- layout: archive title: Zulip Chat Archive permalink: /stream/113488-general/topic/mathlib.20nightly.20dependence.html ---
could mathlib stop depending on nightlies?
In lieu of what?
the latest lean commit that builds?
That's what we used to do, gave headaches for all
04-10 lean compiles, but I'm forced to detach head from lean and use the 04-04 version
just because it compiles doesn't mean it works with mathlib
right
If I increase the nightly version that means I've tested it with the latest changes, other than that I make no guarantee
By attaching to a particular nightly version it prevents the situation where Leo pushes some breaking change and mathlib is broken for a week while we figure out how to recover from it
I see
It's fully possible that mathlib works with no changes on 4-10 nightly, and I'll probably update it next time I make a change to mathlib, but unless there's some feature that was just added that you need it shouldn't cause you any problems to just stay on 04-04
it doesn't work with 4-10
Also, mathlib is currently broken w.r.t. Lean head, until https://github.com/leanprover/lean/pull/1955 is merged
@Kenny Lau Are you still compiling Lean yourself? Why?
why not?
Because of the added friction you complain about here...
If you haven't seen https://github.com/Kha/elan yet, it will solve the issue of how to obtain a Lean version compatible to mathlib. Though I don't know what OS you're using.
 I have precise control over which commits I rely on. Also, I compile Lean much less often than nightlies are made, so I don't think I'm contributing much to climate change. :wink:
$ curl https://raw.githubusercontent.com/Kha/elan/master/elan-init.sh -sSf | sh info: downloading installer curl: (22) The requested URL returned error: 404 Not Found elan: command failed: curl -sSfL https://github.com/Kha/elan/releases/download/v0.3.0/elan-x86_64-pc-windows-gnu.zip -o /tmp/tmp.xOB7DmPlna/elan-init.zip
@Kenny Lau I'll take a look, thanks
@Sean Leather Just for completeness, elan should give you exactly the same amount of control. Well, you can't select commits between nightlies, but hopefully that should be granular enough.
@Sebastian Ullrich Thanks. I'll wait and see how it goes. I do like being able to choose commits, but I grant you that is probably not an important requirement. At the moment, anyway, I don't feel the need to change my approach.
There's also a certain argument that us "early adopters" hanging out here should dogfood elan, to make sure it's usable for the newcomers.
How widespread do you expect Lean to get :)? Can we go by how Coq's doing after 30 years?
:-)
I'm enormously encouraged by the fact that my undergrads can learn Lean, and do non-trivial stuff in it.
@Sebastian Ullrich I believe Elan is still using the wrong tool for unzipping on Mac
Well yes, I haven't touched it yet :)
I think that's the wrong approach to fixing it :stuck_out_tongue_closed_eyes:
{% endraw %}Last updated: Apr 24 2020 at 19:02 UTC


23 sept 2017
Barlok, Brussels
ambient / noise / experimental / drone
indrustrial / techno / hardcore
At: 15:00 - 18:00
Slovak experimental artist and music instruments creator Jonáš Gruska is going to lead you in the making of an electromagnetic listening device "Elektrosluch". Elektroslusch is an open-source device for electromagnetic listening. It allows one to discover sonic worlds of electromagnetic fields that are invisible ever present part of our environment. After the workshop you are going to be able to just plug your headphones in the new miniaturised version of Elektrosluch and explore your surroundings.
All the necessary parts, including battery are provided but there are two things you need to bring:
- soldering iron,
- headphones.
If you don't have a soldering iron and don't have any experience with soldering don't worry. Jonáš is going to show you the basics and we can lend you one.
Here is how it works and sounds
Places are limited to 12 people. Jonáš is going to bring all parts from Slovakia so please send us an e-mail to confirm your interest in advance until 21st of September to superclusterfestival (at) gmail.com Cost is 50 EUR.
Venue: Barlok, 53 bis avenue du Port, 1000 Brussels
RSVP: Facebook event


31-October-2019 - 6.19.0
The PMD team is pleased to announce PMD 6.19.0.
This is a minor release.
New and noteworthy
Updated PMD Designer
This PMD release ships a new version of the pmd-designer. For the changes, see PMD Designer Changelog.
Java Metrics
- The new metric “Class Fan Out Complexity” has been added. See Java Metrics Documentation for details.
Modified Rules
-
The Java rules
InvalidLogMessageFormat
andMoreThanOneLogger
(java-errorprone
) now both support Log4j2. Note that the rule “InvalidSlf4jMessageFormat” has been renamed to “InvalidLogMessageFormat” to reflect the fact, that it now supports more than slf4j. -
The Java rule
LawOfDemeter
(java-design
) ignores now also Builders, that are not assigned to a local variable, but just directly used within a method call chain. The method, that creates the builder needs to end with “Builder”, e.g.newBuilder()
orinitBuilder()
works. This change fixes a couple of false positives. -
The Java rule
DataflowAnomalyAnalysis
(java-errorprone
) doesn’t check for UR anomalies (undefined and then referenced) anymore. These checks were all false-positives, since actual UR occurrences would lead to compile errors. -
The java rule
DoNotUseThreads
(java-multithreading
) has been changed to not report usages ofjava.lang.Runnable
anymore. Just usingRunnable
does not automatically create a new thread. While the check forRunnable
has been removed, the rule now additionally checks for usages ofExecutors
andExecutorService
. Both create new threads, which are not managed by a J2EE server.
Renamed Rules
- The Java rule
InvalidSlf4jMessageFormat
has been renamed toInvalidLogMessageFormat
since it supports now both slf4j and log4j2 message formats.
Fixed Issues
- core
- #1978: [core] PMD fails on excluding unknown rules
- #2014: [core] Making add(SourceCode sourceCode) public for alternative file systems
- #2020: [core] Wrong deprecation warnings for unused XPath attributes
- #2036: [core] Wrong include/exclude patterns are silently ignored
- #2048: [core] Enable type resolution by default for XPath rules
- #2067: [core] Build issue on Windows
- #2068: [core] Rule loader should use the same resources loader for the ruleset
- #2071: [ci] Add travis build on windows
- #2072: [test][core] Not enough info in “test setup error” when numbers of lines do not match
- #2082: [core] Incorrect logging of deprecated/renamed rules
- java
- #2042: [java] PMD crashes with ClassFormatError: Absent Code attribute…
- java-bestpractices
- java-codestyle
- #2017: [java] UnnecessaryFullyQualifiedName triggered for inner class
- java-design
- #1912: [java] Metrics not computed correctly with annotations
- java-errorprone
- java-multithreading
- #1627: [java] DoNotUseThreads should not warn on Runnable
- doc
- #2058: [doc] CLI reference for
-norulesetcompatibility
shows a boolean default value
- #2058: [doc] CLI reference for
API Changes
Deprecated APIs
For removal
- pmd-core
- All the package
net.sourceforge.pmd.dcd
and its subpackages. SeeDCD
. - In
LanguageRegistry
: RuleSet#getExcludePatterns
. Use the new methodgetFileExclusions
instead.RuleSet#getIncludePatterns
. Use the new methodgetFileInclusions
instead.Parser#canParse
Parser#getSuppressMap
RuleBuilder#RuleBuilder
. Use the new constructor with the correct ResourceLoader instead.RuleFactory#RuleFactory
. Use the new constructor with the correct ResourceLoader instead.
- All the package
- pmd-java
CanSuppressWarnings
and its implementationsisSuppressed
getDeclaringType
.isSupressed
ASTMethodDeclarator
getMethodName
getBlock
getParameterCount
- pmd-apex
CanSuppressWarnings
and its implementationsisSupressed
Internal APIs
- pmd-core
- All the package
net.sourceforge.pmd.util
and its subpackages, exceptnet.sourceforge.pmd.util.datasource
andnet.sourceforge.pmd.util.database
. GridBagHelper
ColumnDescriptor
- All the package
External Contributions
- #2010: [java] LawOfDemeter to support inner builder pattern - Gregor Riegler
- #2012: [java] Fixes 336, slf4j log4j2 support - Mark Hall
- #2032: [core] Allow adding SourceCode directly into CPD - Nathan Braun
- #2047: [java] Fix computation of metrics with annotations - Andi Pabst
- #2065: [java] Stop checking UR anomalies - Carlos Macasaet
- #2068: [core] Rule loader should use the same resources loader for the ruleset - Chen Yang
- #2070: [core] Fix renderer tests for windows builds - Saladoc
- #2073: [test][core] Add expected and actual line of numbers to message wording - snuyanzin
- #2076: [java] Add Metric ClassFanOutComplexity - Andi Pabst
- #2078: [java] DoNotUseThreads should not warn on Runnable #1627 - Michael Clay


--- layout: post title: Create a new task in Todoist using Alfred categories: tags: front-page: true ---
I recently made the switch back to Apple OSX on my laptop. Since doing so I have enjoyed using Alfred to streamline my productivity. I also use Todoist for my task management needs - it is simple, pretty, and cross-platform. The Todoist OSX application provides the ability to quickly add tasks via a hot-key combination. But I like to keep things simple. Ideally I would like one application to serve as my proxy to all things productivity - I would like that application to be Alfred. So naturally this leads to the question of how to add a new task Todoist via Alfred.
Alfred provides the ability to create custom workflows - AWESOME! This is exactly what I need. What I want is to…
Use cURL to make a call to Todoist's API to add a new item. I need to provide the content of the new task along with my user specific API_TOKEN. The API_TOKEN can be found in the settings of your Todoist application.
Figure 1: Accessing todoist settings
Figure 2: Finding my API_TOKEN
Making the call to Todoist's API to add a new item.
# post a new note with given conent to todoist via API # NOTE: Todoist syntax is respected -- see label and priority below curl -X POST -d 'content=my shiny new task @mylabel !p1' \ -d 'token=my-api-token' https://todoist.com/API/additem
Invoke Alfred's preferences menu.
Create a new Blank Workflow.
Create a new Keyword Input
Create a new Run Script Action
And add the following content to the script action. Note the use of {query} to grab the content from our keyword trigger.
# Add a new task to the default project of my Todoist # ------------------------------------------------------------ # Todoist API token (this can be found in Todoist account info) API_TOKEN=my-api-token # grab the new task content new_task_content="{query}" # post a new note with given conent to todoist via API # NOTE: Todoist syntax is respected -- see label and priority below curl -X POST -d "content=$new_task_content !p1" \ -d "token=$API_TOKEN" https://todoist.com/API/additem exit 0
Also, be sure to uncheck all escaping options - if this is not done you will end up with a bunch of backslashes in your task content.
Runn the workflow
So this works great! I can add tasks to Todoist right from Alfred just like I want! The only thing missing is confirmation that the task was successfully added to Todoist, or a warning if the task could not be posted.
When we successfully post the task we get an output similar to this:
{ "due_date": null "assigned_by_uid": XXXXXXX "is_archived": 0 "labels": [] "sync_id": null "in_history": 0 "has_notifications": 0 "date_added": "Fri 02 Jan 2015 02:07:04 +0000" "indent": 1 "children": null "content": "my shiny new task" "is_deleted": 0 "user_id": XXXXXXX "due_date_utc": null "id": XXXXXXXX "priority": 1 "item_order": 4 "responsible_uid": null "project_id": XXXXXXXXX "collapsed": 0 "checked": 0 "date_string": "" }
Given this, I will assume that a successful post is confirmed if the first character of the returned string is { and the last character is }.
I can modify my script to check for success based on this assumption.
# Add a new task to the default project of my Todoist # ------------------------------------------------------------ # Todoist API token (this can be found in Todoist account info) API_TOKEN=my-api-token # grab the new task content new_task_content="{query}" # post a new note with given content to todoist via API # NOTE: Todoist syntax is respected -- see label and priority below result=$(curl -X POST -d "content=$new_task_content !p1" \ -d "token=$API_TOKEN" https://todoist.com/API/additem) # get the first and last characters of the result first_char=${result:0:1} last_char=${result: -1} # output the appropriate message given the result exit_status=0 if [[ $first_char == "{" && $last_char == "}" ]]; then echo "New task created!" else echo "Error encountered whilst trying to create new task" exit_status=1 fi exit $exit_status
Create a new Post Notification Output.
My finished workflow.


RaNNC (Rapid Neural Network Connector)¶
RaNNC is a deep learning framework for automatic model/data parallelism. RaNNC decomposes a computational graph of a PyTorch model and distributes the subgraphs onto multiple compute nodes. You can train a billion-scale parameter models using RaNNC.
Automatic Graph Partitioning for Very Large-scale Deep Learning, Masahiro Tanaka, Kenjiro Taura, Toshihiro Hanawa and Kentaro Torisawa, In the Proceedings of 35th IEEE International Parallel and Distributed Processing Symposium (IPDPS 2021), Portland, Oregon USA, May, 2021. (to appear)
Installation¶
Prerequisites¶
RaNNC works only with CUDA devices (CPU only/TPU environments are not supported). RaNNC requires following libraries and tools at runtime.
CUDA: A CUDA runtime must be available at the runtime environment. Currently RaNNC is tested with CUDA 10.2.
NCCL: NCCL (Version >= 2.7.3 is required) must be available at the runtime environment. RaNNC uses NCCL both for allreduce and P2P communications.
MPI: A program using RaNNC must be launched with MPI. MPI libraries must also be available at runtime. RaNNC is tested with OpenMPI v4.0.5.
libstd++:
libstd++
must supportGLIBCXX_3.4.21
to use the distributedpip
packages (The packages are built with gcc 5.4.0).
Installation¶
This version of RaNNC requires PyTorch v1.7.1.
pip
packages for linux_x86_64
are available from the following links.
For Python 3.7
For Python 3.8
You can create a new conda environment and install RaNNC by the following commands.
conda create -n rannc python=3.8
conda activate rannc
conda install pytorch==1.7.1 cudatoolkit=10.2 -c pytorch
pip install pyrannc-0.5-cp38-cp38m-linux_x86_64.whl
Tutorial¶
RaNNC distributes PyTorch models onto multiple nodes or processes using MPI. Follow the steps below to learn the basic usage of RaNNC.
Steps to use RaNNC¶
0. Set up environment¶
Ensure required tools and libraries (CUDA, NCCL, OpenMPI, etc.) are available.
The libraries must be included in LD_LIBRARY_PATH
at runtime.
2. Wrap your model¶
Wrap your model by pyrannc.RaNNCModule
with your optimizer.
You can use the wrapped model in almost same manner as the original model (See below).
Note that the original model must be on a CUDA device.
model = Net()
model.to(torch.device("cuda"))
opt = optim.SGD(model.parameters(), lr=0.01)
model = pyrannc.RaNNCModule(model, optimizer)
If you don’t use an optimizer, pass only the model.
model = pyrannc.RaNNCModule(model)
3. Run forward/backward passes¶
A RaNNCModule
can run forward/backward passes as with a torch.nn.Module
.
x = torch.randn(64, 3, requires_grad=True).to(torch.device("cuda"))
out = model(x)
out.backward(torch.randn_like(out))
Inputs to RaNNCModule
must be CUDA tensors.
RaNNCModule has several more limitations about a wrapped model and inputs/outputs.
See Limitations for details.
The optimizer can update model parameters just by calling step()
.
The program below (examples/tutorial_usage.py
) shows the above usage with a very simple model.
import torch
import torch.nn as nn
import torch.optim as optim
import pyrannc
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(3, 2, bias=False)
self.fc2 = nn.Linear(2, 3, bias=False)
def forward(self, x):
x = self.fc1(x)
x = self.fc2(x)
return x
model = Net()
model.to(torch.device("cuda"))
opt = optim.SGD(model.parameters(), lr=0.01)
model = pyrannc.RaNNCModule(model, opt)
x = torch.randn(64, 3, requires_grad=True).to(torch.device("cuda"))
out = model(x)
target = torch.randn_like(out)
out.backward(target)
opt.step()
4. Launch¶
A program using RaNNC requires to be launched by mpirun
.
You can launch the above example script by:
mpirun -np 2 python tutorial_usage.py
-np
indicates the number of ranks (processes).
RaNNC allocates one CUDA device for each rank.
In the above example, there must be two available CUDA devices.
How RaNNC works¶
Automatic parallelism¶
RaNNC analyzes a given model and determines the best combination of different parallelisms. RaNNC can combine the three following parallelisms.
Data parallelism
Model parallelism
Pipeline parallelism
See IPDPS 2021 paper for the details of the automatic parallelism.
Data distribution¶
Each process launched by MPI is expected to load different (mini-)batches. RaNNC automatically gathers the batches from all ranks and compute them as one batch.
torch.utils.data.distributed.DistributedSampler
will be useful for this purpose.
Limitations¶
Although a RaNNCModel
is designed to work like torch.nn.Module
, it has the following limitations.
Control constructs are ignored¶
RaNNC uses a computation graph produced by PyTorch’s tracing function. As explained in the document, the tracing function does not record control constructs including conditional branches and loops.
Arguments and return values¶
Arguments and outputs of a RaNNCModel
must satisfy the following conditions.
Arguments must be (mini-)batches tensors, whose first dimension corresponds to samples in a mini-batch.
Keyword arguments are not allowed.
Outputs must be (mini-)batches tensors, or a loss value (scalar tensor).
Tensor data types¶
Currently RaNNC does not support TF32 (TensorFloat-32).
FAQs¶
Does RaNNC work with Apex AMP?¶
Yes.
Convert your model with amp.initialize()
and pass
the resulting model to RaNNCModule
with use_amp_master_params=True
.
How to save/load a RaNNC module¶
Use state_dict()
of the RaNNC module.
The returned state_dict can be saved and loaded as with PyTorch.
Please make sure state_dict()
must be called from all ranks.
Otherwise, the call of state_dict()
is blocked because RaNNC gathers parameters across all ranks.
How to use gradient accumulation¶
As default, RaNNC implicitly performs allreduce (sum) of gradients on all ranks after a backward pass.
To prevent the allreduce, you can use pyrannc.delay_grad_allreduce(False)
.
After a specified number of forward/backward steps, you can explicitly perform allreduce
with allreduce_grads
of your RaNNCModule
.
My model takes too long until partitioning is determined¶
By setting save_deployment=true
, RaNNC outputs the deployment state to a file deployment_file
after
partitioning is determined. You can load the deployment file by setting load_deployment=true
.
This greatly save your time if you run a program using RaNNC with similar settings, e.g. with different learning rate.
(See also Configurations)
When you are unsure that partitioning process keeps going or already failed, you can change the log level of
the partitioning module. Changing log levels of MLPartitioner
and DPStaging
will show you the progress of
partitioning process.
(See also Logging)
API References¶
Logging¶
RaNNC uses spdlog and
spdlog_setup for logging.
You can configure the logging by a configuration file
placed at ~/.pyrannc/logging.toml
.
Since RaNNC has loggers associated with internal modules, you can set a log level for each module. The below shows an example of the loggign configuration file.
global_pattern = "[%Y-%m-%d %T.%f] [%L] <%n>: %v"
# Sinks
[[sink]]
name = "console_st"
type = "stdout_sink_st"
[[sink]]
name = "stderr_st"
type = "color_stdout_sink_st"
# Loggers
[[logger]]
name = "root"
sinks = ["console_st"]
level = "info"
[[logger]]
name = "RaNNCModule"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "RaNNCProcess"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "GraphLauncher"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "GraphValueStorage"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "GraphUtil"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "Decomposer"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "Decomposition"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "GraphProfiler"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "ParamStorage"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "GraphConnector"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "TorchDriver"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "AllReduceRunner"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "MLPartitioner"
sinks = ["stderr_st"]
level = "info"
[[logger]]
name = "DPStaging"
sinks = ["stderr_st"]
level = "info"
Building from source¶
Compiler version¶
You must use GCC v5.4 or newer. We tested RaNNC with GCC v5.4 and v7.1. Note that, however, RaNNC must be built complying ABI of PyTorch.
RaNNC is built with Pre-cxx11 ABI (_GLIBCXX_USE_CXX11_ABI=0
) as default because PyTorch installed via conda is built with Pre-cxx11 ABI.
You can change the ABI setting in CMakeLists.txt
.
PyTorch provides you with a function below to know how the binary is compiled.
Build and Install¶
You need to set some environment variables before building RaNNC to help cmake find dependent libraries.
Variable |
|
CUDA_HOME |
Path to a CUDA runtime directory. |
MPI_DIR |
Path to an MPI installation directory. |
BOOST_DIR |
Path to a Boost libraries directory. |
CUDNN_ROOT_DIR |
Path to a cuDNN libraries directory. |
LD_LIBRARY_PATH |
Must contain the path to NCCL lib directory. |
The building process refers to PyTorch installed with conda.
Therefore, install PyTorch with your python and run setup.py
.
The following script shows configurations to install RaNNC from the source.
#!/usr/bin/env bash
# Activate conda
source [CONDA_PATH]/etc/profile.d/conda.sh
conda activate rannc
# Set dependencies
export CUDA_HOME="$(dirname $(which nvcc))/../"
export MPI_DIR="$(dirname $(which ompi_info))/../"
export BOOST_DIR=[BOOST_DIR_PATH]
export CUDNN_ROOT_DIR=[YOUR_CUDNN_DIR_PATH]
python setup.py build -g install
Makefiles under docker/
show the complete process to build and install RaNNC.
They are used to build pip packages.
Configurations¶
RaNNC’s runtime configurations can be set in the following two ways:
Config file: RaNNC automatically loads a configuration file at
~/.pyrannc/rannc_conf.toml
. Names of configuration items must be in lower case. The path to the configuration file can be set by an environment variableRANNC_CONF_DIR
.Environment variables: You can overwrite configuration by setting environment variables. Names of variables follows
RANNC_<CONF_ITEM_NAME>
in upper case. For example, you can set mem_margin in the following table by a variableRANNC_MEM_MARGIN
.
Name |
Default |
|
|---|---|---|
mem_margin |
0.1 |
Memory margin for model partitioning. |
save_deployment |
true |
Save deployment of a partitioned model if set to true. |
load_deployment |
false |
Load deployment of a partitioned model if set to true. |
deployment_file |
|
Path of deployment file to save/load. |
min_pipeline |
1 |
Minimum number of microbatches for pipeline parallelism |
max_pipeline |
32 |
Maxmum number of microbatches for pipeline parallelism |
opt_param_factor |
2 |
Factor to estimate memory usage by an optimizer. For example, Set this item to 2 for Adam because the optimizer uses two internal data v and s, whose sizes are equivalent to parameter tensors. |
trace_events |
false |
Trace internal events if set to true. When true, the event tracing significantly degrades performance. |
event_trace_file |
|
Path to an event trace file. |
The following is an example of the configuration file.
profiling=false
dump_graph=false
dump_graph_prefix="graph_dump"
partition_num=2
replica_num=1
pipeline_num=1
validate_comm=false
display_comm_value=false
profiling_iter=1
consolidate_grads=false
checkpointing=true
checkpointing_no_last=false
auto_parallel=false
p2p_comm=true
opt_param_factor=2
min_partition_num=5
max_partition_num=30
mem_margin=0.1
do_uncoarsening=true
min_pipeline=1
max_pipeline=4
save_deployment=true
load_deployment=false
save_graph_profile=false
load_graph_profile=false
trace_events=false
verify_recomp=false
coarsen_by_time=false
skip_grad_scaling=false


Algorithm: Bubble sort
Method: Exchanging
Average Performance: О(n²)
Stable: Yes
Algorithm: Insertion sort
Method: Insertion
Average Performance: О(n²)
Stable: Yes
Algorithm: Merge sort
Method: Merging
Average Performance: О(n log n)
Stable: Yes
Algorithm: Heap sort
Method: Selection
Average Performance: О(n log n)
Stable: No


Infiniti Finally Updates Its Infotainment System With Good Graphics, Latest Features
Apple CarPlay and Android Auto at last.
by Nico YlananIf you've been put off by the offerings of Infiniti because they were relatively lagging behind in terms of in-car connectivity and infotainment, we have some good news for you. Infiniti has just announced that it will be rolling out their next-generation Infiniti InTouch infotainment systems to key vehicles by the 2020 model year, namely the Q50, Q60, QX50 and the flagship QX80. It still uses the same dual-screen setup, but it looks like the user interface and overall aesthetic has been redesigned to stay competitive in an age where we just have to plug our phones in and start driving.
Gallery: 2019 Infiniti QX60 Limited
We finally see the integration of Apple CarPlay and Android Auto (depending on certain markets) via a wired connection, ditching the rather finicky wireless versions. There will also be a much improved navigation software that takes note of real-time traffic info, rerouting based on live traffic conditions, turn-by-turn directions, and 3D maps. There's also a Wi-Fi hotspot where up to seven devices can connect at a time, and over-the-air updates are also finally supported to keep things like maps and relevant software up-to-date. The experience is also said to be faster thanks to a better performing processor.
Technology Has It's Perks And Quirks:
Eric Rigaux, General Manager of Product Strategy and Planning for Infiniti had this to say: "Having listened to feedback from our customers, we have vastly improved the system's features, intuitive use and functionality. It was important for us to offer both Apple CarPlay and Android Auto as standard in our new models to allow the majority of drivers to connect their smartphones to the car. The latest INFINITI InTouch™ with dual screens makes in-car connectivity easy and informative, meaning drivers and passengers can enjoy the benefits intuitively while driving."
Could we be seeing this system trickle down into the Nissans soon? We hope so.
Source: Infiniti


Introduction
Welcome to the Structurely API!
These endpoints are used by partners to embed Structurely within your offering.
If you are intestested in working with us via our API please contact us at<EMAIL_ADDRESS>Authentication
All requests to the API in must include the header X-Api-Authorization with your API key. To get an API key please contact us.
Overview
Endpoints
All endpoints are hosted by the domain api.structurely.com
. All requests must use https
. Any request with the protocol http
will be redirected to https
with the status code 301. The path for the api will always start with /v1
. Every resource endpoint will start with https://api.structurely.com/v1
.
Types
| Type | Description |
|---|---|
ObjectId |
A 24 byte hexadecimal string. See ObjectId. |
Boolean |
A JSON boolean represented by either true or false . |
Integer |
A plain integer. May be restricted by an interval (i.e. Intenger[0,) , Integer[0,10] , Integer(0,100] ). |
Float |
A floating point number. |
String |
A plain string. When used as a url or query parameter, it must be url escaped. |
DateTime |
A date time string that can be parsed into a time zone aware date time object. |
List |
An array of values of either a primitive type or a schema. Usually has a type name defined (i.e. List<Agent> , List<Integer> ) |
Enum |
A single value that can be any primative type. Always has a set of possible values defined (i.e. Enum{'hello', 'world'} , Enum{0, 1, 2} ) |
Conversations
The Conversation API is a resource, that represents a conversational exchange with Structurely. This resource allows you to interface your CRM directly with Structurely.
Create Conversation
curl 'https://api.structurely.com/v1/conversations' \
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "settings": { "timeZone": "America/Chicago" }, "slots": [{ "name": "email", "value"<EMAIL_ADDRESS>}, { "name": "lead_type", "value": "buyer" }, { "name": "lead_type", "value": "seller" }, { "name": "external_lead_id", "value": "63dae72910b57fd51d0d9652"}], "messages": []}'
The above command returns JSON structured like this:
{
"id": "5c09a4416241ea2c293275b8",
"settings": {
"chatbotName": "Aisa",
"timeZone": "America/Chicago"
},
"slots": [
{
"name": "email",
"value"<EMAIL_ADDRESS>},
{
"name": "lead_type",
"value": "buyer"
},
{
"name": "lead_type",
"value": "seller"
}
],
"muted": false
}
This endpoint creates and returns a new conversation object.
HTTP Request
POST https://api.structurely.com/v1/conversations
Body Parameters[^]
| Parameter | Type |
|---|---|
| settings | ConversationSettings |
| slots | List<ConversationSlot> |
| muted | Boolean |
| messages | List<ConversationItem> |
Extra slots for tracking
Set these optional slots to facilitate reporting and querying of conversations using IDs in your own system. Store these optional IDs by sending them as slots with string values. These IDs are persisted internally but not emitted as slots when conversations are retrieved over the API.
| Slot Name | Purpose |
|---|---|
| external_account_id | Associate this conversation to its account's ID |
| external_team_id | Associate this conversation to its team's ID |
| external_user_id | Associate this conversation to its user's ID |
| external_lead_id | Associate this conversation to its lead's ID |
Get Conversation
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"id": "5c09a4416241ea2c293275b8",
"settings": {
"chatbotName": "Aisa",
"timeZone": "America/Chicago"
},
"slots": [
{
"name": "name",
"value": "John Doe"
},
{
"name": "email",
"value"<EMAIL_ADDRESS>},
{
"name": "phone",
"value": "+15551234567"
},
{
"name": "address",
"value": "123 Main St."
},
{
"name": "agent_name",
"value": "Andi Agent"
},
{
"name": "lead_type",
"value": "buyer"
},
{
"name": "lead_type",
"value": "seller"
}
],
"muted": false
}
This endpoint returns a specific conversation.
HTTP Request
GET https://api.structurely.com/v1/conversations/<id>
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation to retrieve |
Response Body[^]
Update Conversation
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8' \
-X PATCH \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "muted": true }'
The above command returns JSON structured like this:
{
"id": "5c09a4416241ea2c293275b8",
"settings": {
"chatbotName": "Aisa",
"timeZone": "America/Chicago"
},
"slots": [
{
"name": "email",
"value"<EMAIL_ADDRESS>}
],
"muted": true
}
This endpoint updates and returns a specific conversation object.
HTTP Request
PATCH https://api.structurely.com/v1/conversations/<id>
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation to update |
Body Parameters
| Parameter | Type | Description |
|---|---|---|
| muted | Boolean |
Once muted, a conversation can still receive messages but will no longer generate replies. It is not possible to unmute a conversation. |
Response Body[^]
Insert Slots
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/slots' \
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '[{ "name": "agent_name", "value": "Andi Agent" }]'
The above command returns an empty body with a 204 response
This endpoint inserts the given slots to the conversation. Multi-valued slots will append the new values rather than replacing them. Returns a 204 response with an empty body.
HTTP Request
POST https://api.structurely.com/v1/conversations/<id>/slots
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation insert slots to |
Body Parameters
The body is a list of objects
| Type | Description |
|---|---|
List<ConversationSlot> |
The list of conversation slot objects |
Update Slots
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/slots' \
-X PATCH \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '[{ "name": "agent_name", "value": "Andi Agent" }]'
The above command returns an empty body with a 204 response
This endpoint updates the given slots to the conversation. Multi-valued slots will be overwritten with the new values replacing the old ones. Returns a 204 response with an empty body.
HTTP Request
PATCH https://api.structurely.com/v1/conversations/<id>/slots
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation insert slots to |
Body Parameters
The body is a list of objects
| Type | Description |
|---|---|
List<ConversationSlot> |
The list of conversation slot objects |
Upsert Slot
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/slots/agent_name' \
-X PUT \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '["Andi Agent"]'
The above command returns an empty body with a 204 response
This endpoint updates the exsting slot with that name to the list of values provided. All slots, both multi-valued and single-valued are provided in an array. Make the array a single element array if the slot is single-valued. If the slot does not already exist with that name, it is inserted with all the values provided.
HTTP Request
PUT https://api.structurely.com/v1/conversations/<id>/slots/<name>
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation insert slots to |
| name | The name of the slot to update or insert |
Body Parameters
The body is a list of values
| Type | Description |
|---|---|
List<Any> |
The list of slot values |
Create Message
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/messages'
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "text": "Hello World", "received": "2018-12-09T11:44:00.000Z" }'
The above command returns JSON structured like this:
{
"_metadata": {
"conversation": "5c09a4416241ea2c293275b8",
"messages": 2,
"responses": 1
},
"message": {
"id": "5c09a45e6241ea2c293275bf",
"text": "Hello World",
"received": "2018-12-09T11:44:00.000Z"
}
}
This endpoint creates a new lead message for the conversation for us to extract and classify.
HTTP Request
POST https://api.structurely.com/v1/conversations/<id>/messages
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation to create a message for |
Body Parameters[^]
| Parameter | Type |
|---|---|
| text | String |
| received | DateTime |
Create Response
curl 'https://api.structurely.com/v1/conversations/5c09a4416241ea2c293275b8/responses'
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "_metadata": { "context": "expect_showing_appointment" }, "text": "Hello There", "received": "2018-12-09T11:44:00.000Z" }'
The above command returns JSON structured like this:
{
"_metadata": {
"conversation": "5c09a4416241ea2c293275b8",
"context": "expect_showing_appointment",
"messages": 2,
"responses": 2
},
"response": {
"id": "5c09a4416241ea2c293275b5",
"text": "Hello There",
"received": "2018-12-09T11:44:00.000Z"
}
}
This endpoint creates a new system response for the conversation. This does nothing in our system other than act as a send receipt notifying us that an outbound message was sent on behalf of the system/realtor.
HTTP Request
POST https://api.structurely.com/v1/conversations/<id>/responses
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation to create a message for |
Body Parameters[^]
| Parameter | Type |
|---|---|
| _metadata | MessageMetaData |
| text | String |
| received | DateTime |
Schemas
Conversation
| Field | Type | Description | Readable? | Writable? | Required? | Default |
|---|---|---|---|---|---|---|
| id | ObjectId |
The ID of the conversation this resource represents. | Yes | No | No | |
| settings | ConversationSettings |
The settings for to use for this conversation. | Yes | No | Yes | |
| slots | List<ConversationSlot> |
A list of extracted or pre-filled values relating to the conversation. | Yes | No | Yes | |
| muted | Boolean |
A boolean flag to tell whether or not this conversation is muted. Once muted, a conversation can still receive messages but will no longer generate replies. It is not possible to unmute a conversation. | Yes | Yes | No | false |
| stages | List<String> |
A list of stages this conversation is currently in. | Yes | No | No | |
| messages | List<ConversationItem> |
A list of lead messages and system responses with the context value with each response. | No | No | Yes |
ConversationSettings
| Field | Type | Description | Readable? | Writable? | Required? | Default |
|---|---|---|---|---|---|---|
| timeZone | String |
The time zone the realtor and/or lead. (See list) | Yes | No | Yes | |
| chatbotName | String |
The name of conversation AI to use in responses. | Yes | No | No | Aisa |
| leadTypes | List<String> |
The lead types that will be supported in this conversation. Possible values are buyer , seller , and renter |
Yes | No | No | ['buyer', 'seller'] |
| allowedDomains | List<String> |
The domains that this conversation can use for conversation flows. Possible values are real_estate and mortgage . When a lead sets or changes its lead type, the domain determines what scripts to use. |
Yes | No | No | ['real_estate'] |
| dripCampaignEnabled | Boolean |
If set to true, Structurely drip campaigns will be used for an unresponsive lead. Only runs if there is no lead message following a system response in the messages list. | Yes | No | false |
|
| reDripsEnabled | Boolean |
If set to true, Structurely will re-engage leads that have responded but are not responding to the current prompt. Will use the current context to determine outbound re-drips even if a custom response is generated by the third party user. | Yes | No | false |
ConversationSlot
| Field | Type | Description | Readable? | Writable? | Required? |
|---|---|---|---|---|---|
| name[a] | String |
The name of the slot. | Yes | No | Yes |
| value[a] | Any |
The value of the slot. | Yes | No | Yes |
ConversationItem
| Field | Type | Description | Readable? | Writable? | Required? |
|---|---|---|---|---|---|
| message | Message |
A message the lead sent. | No | Yes | Yes[1] |
| respone | Message |
A respone sent by the system. | No | Yes | Yes[1] |
| context[b] | String |
The context set by the response in this conversation item. | No | Yes | Yes[2] |
message
andresponse
are mutually exclusive. At least one is required to be present but not both.context
is only required if theresponse
field is used.
Message
| Field | Type | Description | Readable? | Writable? | Required? |
|---|---|---|---|---|---|
| text | String |
The text of the message. | No | Yes | Yes |
| received | DateTime |
The time the message was sent or received. | No | Yes | Yes |
| _metadata[1] | MessageMetaData |
An optional metadata object to set the outgoing context for a response. | No | Yes | No |
_metadata
is only used when creating a response object.
MessageMetaData
| Field | Type | Description | Readable? | Writable? | Required? |
|---|---|---|---|---|---|
| context | String |
The outgoing context of this response. Used by Structurely to classify messages sent after this response. | No | Yes | No |
Slots, Contexts, and Stages
Slots
| Name | Type | Description |
|---|---|---|
| Lead Contact Information | ||
| name | String |
The name of the lead. |
String |
The email of the lead. | |
| phone | String |
The phone number of the lead. |
| address | String |
The address of the property a buyer lead is interested in. |
| selling_address | String |
The address of the property a seller lead is trying to sell. |
| lead_type | List<String> |
A list of lead types this lead is considered as. Not limited to but includes any of buyer , buyer_specific , renter , renter_specific , seller , just_looking , pending_sale_interest , investor , rent_to_own , rent_to_own_specific , new_home_loan , new_home_loan_specific , home_refinance or a combination thereof. |
| Agent Contact Information | ||
| agent_name | String |
The name of the agent Structurely is messaging on the behalf of. |
| agent_email | String |
The email of the agent. |
| agent_phone | String |
The phone of the agent. |
| agency_name | String |
The name of the agency the agent works for or Structurely is messaging on the behalf of. |
| office_location | String |
The general location of the realtor office the system is representing. |
| Slots for Tracking Purposes | ||
| external_account_id | String |
Associate this conversation to its account's ID |
| external_team_id | String |
Associate this conversation to its team's ID |
| external_user_id | String |
Associate this conversation to its user's ID |
| external_lead_id | String |
Associate this conversation to its lead's ID |
| General Lead Information | ||
| agent_status | Boolean |
True if the lead is already working with an agent. |
| alternate_plan | String |
|
| appointment | String |
The time the lead is available for an appointment. |
| baths | Float |
The specific number bathrooms the lead is looking for. |
| baths_min | Float |
The minimum number of bathrooms the lead is looking for. |
| baths_max | Float |
The maximum number of bathrooms the lead is looking for. |
| beds | Integer |
The specific number of bedrooms the lead is looking for. |
| beds_min | Integer |
The minimum number of bedrooms the lead is looking for. |
| beds_max | Integer |
The maximum number of bedrooms the lead is looking for. |
| benefit | Boolean |
|
| business_development | Enum |
Business development. Possible values:{'outbound', 'inbound', 'paid', 'referral', 'networking'} |
| call_availability | String |
The time when the lead is available for a call with the agent. |
| company_name | String |
|
| competitor_status | Boolean |
|
| confidence | Enum |
Confidence. Possible values:{'very_confident', 'somewhat_confident', 'not_confident'} |
| contact_confirmation | Boolean |
|
| contact_time | String |
|
| content_offer | Boolean |
|
| contingency | Boolean |
True if the lead needs to sell their current home before buying. |
| credit | Enum |
Credit rating. Possible values:{'very_poor', 'fair', 'good', 'very_good', 'excellent'} |
| credit_score | Integer[300,850] |
|
| debt_to_income | Float[0,50] |
|
| decision_maker | Boolean |
|
| decision_process | String |
|
| delivery_followup | Boolean |
|
| description | String |
|
| down_payment | Float |
|
| down_payment_min | Float |
|
| down_payment_max | Float |
|
| employment_status | Enum |
Employment status. Possible values:{'self_employed', 'employed', 'not_employed'} |
| equity_status | Float |
|
| equity_status_min | Float |
|
| equity_status_max | Float |
|
| favorite_city | String |
|
| financial_default | Enum |
Financial default. Possible values:{'bankruptcy', 'foreclosure', 'short_sale', 'missed_payments'} |
| financing_status | Boolean |
True if the lead is prequalified or paying with cash. |
| first_time_buyer | Boolean |
|
| fsbo_reason | String |
|
| garage_stalls | Integer[0,8] |
Number of garage stalls. |
| garage_stalls_min | Integer[0,8] |
Minimum number of garage stalls. |
| garage_stalls_max | Integer[0,8] |
Maximum number of garage stalls. |
| home_style | Enum |
The home style(s) the lead is interested in. Possible values:{'art_deco', 'barndominium', 'bungalow', 'cape_cod', 'colonial', 'condominium', 'contemporary', 'craftsman', 'creole', 'dutch_colonial', 'farmhouse', 'federal', 'french_provincial', 'georgian', 'gothic_revival', 'greek_revival', 'international', 'italianate', 'log_cabin', 'modern', 'monterey', 'national', 'neoclassical', 'prairie', 'pueblo', 'queen_anne', 'ranch', 'regency', 'saltbox', 'second_empire', 'shed', 'shingle', 'shotgun', 'spanish_eclectic', 'split_level', 'stick', 'tudor', 'victorian', 'other'} |
| image | String |
|
| income | Float |
|
| interest | Enum |
Interest. Possible values:{'interested', 'not_interested', 'somewhat_interested', 'postponed_interested'} |
| is_agent | Boolean |
True if the lead is an agent. |
| is_investor | Boolean |
True if the lead is an investor buying property. |
| is_local | Boolean |
|
| language | Enum |
The language detected in this conversation. Current conversation support is for English and Spanish languages only. Possible values:{'spanish', 'mandarin', 'french', 'hindi', 'arabic', 'portuguese', 'bengali', 'russian', 'japanese', 'punjabi', 'english'} |
| lead_priority | Enum |
Lead priority. Possible values:{'now', 'soon', 'later', 'distant', 'never'} |
| lead_source | String |
The source of the lead. Can be any string. |
| lender_status | Boolean |
|
| listing_appointment | String |
The time the lead is available for an appointment about their listing. |
| listing_url | String |
|
| living_space | Integer |
The living space the lead is searching for. |
| living_space_min | Integer |
The minimum living space the lead is searching for. |
| living_space_max | Integer |
The maximum living space the lead is searching for. |
| loan_balance | Integer |
The loan balance. |
| loan_balance_min | Integer |
The minimum loan balance. |
| loan_balance_max | Integer |
The maximum loan balance. |
| loan_type | Enum |
Loan type. Possible values:{'fha', 'conventional', 'va', 'reverse_mortgage', 'jumbo', 'usda'} |
| location | String |
The general location the lead is interested in buying. |
| lot_size | Integer |
The lot size the lead is searching for. |
| lot_size_min | Integer |
The minimum lot size the lead is searching for. |
| lot_size_max | Integer |
The maximum lot size the lead is searching for. |
| meeting_location | String |
Special values:webcam , zoom , google_hangouts , uberconference , open |
| military_active_duty | Boolean |
|
| military_branch | Enum |
Possible values:{'army', 'air_force', 'coast_guard', 'marines', 'navy', 'national_guard', 'space_force'} |
| military_discharge_type | Enum |
Possible values:{'honorable_discharge', 'general_discharge', 'other_than_honorable_discharge', 'bad_conduct_discharge', 'dishonorable_discharge', 'entry_level_separation', 'medical_separation', 'separation_for_convenience_of_the_government'} |
| military_reserves_service | Boolean |
|
| military_service_term | Integer |
|
| mortgage_escrow | Boolean |
|
| mortgage_intent | Enum |
Possible values:{'preapproval', 'rate_quote'} |
| motivation | Enum |
Possible values:{'new_job', 'lost_job', 'downsizing', 'upsizing', 'death', 'debt', 'divorce', 'lease_expiry', 'lifestyle', 'investment', 'environmental', 'save_money', 'closer_to_family', 'tired_of_renting', 'new_children', 'retiring', 'space_for_animals', 'neighbor_sold_property', 'sold_property', 'ready_to_move', 'closer_to_school', 'closer_to_friends', 'good_schools', 'vacation_interest', 'homeless', 'privacy', 'weather'} |
| motivation_plans | String |
|
| outcome | String |
|
| ownership | Enum |
Possible values:{'sole_owner', 'co_owner', 'third_party_owner', 'no_ownership'} |
| ownership_timeline | String |
Special value: open |
| price | Float |
The specific price the lead is looking for. |
| price_min | Float |
The minimum price the lead is looking for. |
| price_max | Float |
The maximum price the lead is looking for. |
| prior_loan_experience | Boolean |
|
| problem | String |
|
| promotional_offer | Enum |
Interest. Possible values:{'interested', 'not_interested', 'somewhat_interested', 'postponed_interested'} |
| property_feature | Enum |
Possible values:{'access_to_water', 'big_yard', 'detached_garage', 'exposed_beams', 'exposed_brick', 'finished_basement', 'handicap_accessible', 'home_office', 'pool', 'space_to_entertain', 'updated_baths', 'updated_kitchen', 'vaulted_ceilings', 'walkable_neighborhood', 'fenced_yard', 'other'} |
| property_info_request | Enum |
Possible values:{'baths', 'beds', 'boat_slip', 'community_info', 'covenants', 'days_on_market', 'deed_restrictions', 'disclosures', 'expected_dom', 'floorplan', 'garage_spaces', 'hoa', 'living_space', 'lot_rent', 'lot_size', 'owners', 'pet_friendly', 'price', 'property_location', 'property_type', 'public_remarks', 'rental_history', 'schools', 'senior_community', 'status', 'stories', 'taxes', 'transactions', 'utilities', 'year_built', 'zoning'} |
| property_location | String |
|
| property_preferences | String |
|
| property_records | Enum |
Possible values:{'second_mortgage', 'lien'} |
| property_status | Enum |
Possible values:{'active', 'sold', 'pending'} |
| property_type | Enum |
Possible values:{'vacant_land', 'handicap_accessible', 'commercial', 'apartment', 'mobile_home', 'acreage', 'ranch', 'vacation_home', 'residential'} |
| property_use | Enum |
Property use. Possible values:{'vacation', 'investment', 'primary_residence', 'secondary_residence', 'agriculture'} |
| property_value | Float |
|
| property_value_min | Float |
|
| property_value_max | Float |
|
| property_visit | Boolean |
|
| question | Enum |
The question that the lead just asked. Possible values:{'pricing', 'integrations', 'how_it_works', 'features', 'setup_time', 'savings', 'repairs', 'results', 'consultation', 'leasing', 'delivery_time', 'competitive_advantage', 'product_requirements', 'specifications', 'incentives', 'warranty', 'return_on_investment', 'discounts', 'assembly_details', 'referrals', 'compliance', 'available_geography', 'upgrade', 'extension', 'company_details', 'sell_power_back', 'inverter_type', 'license_number', 'data_import', 'quote', 'taxes', 'schools', 'other'} |
| readiness | Enum |
The readiness of the lead. Possible values:{'active', 'just_looking', 'researching', 'not_interested', ''} |
| relocating | Boolean |
|
| savings | Float |
|
| savings_min | Float |
|
| savings_max | Float |
|
| selling_property_description | String |
|
| showing_appointment | String |
The time the lead is available for a showing appointment. |
| tags | String |
General purpose tags for managing and tracking conversations. Will not be asked as a qualifier and is not used to generate responses. |
| technology | String |
Special value: open |
| tenure | String |
|
| time | String |
Special value: open |
| timeframe | String |
The general timeframe a lead is looking to move within. |
| url | String |
|
| veteran | Boolean |
|
| veteran_service_disability | Boolean |
|
| work_history | String |
Contexts
| Name |
|---|
| general |
| expect_address |
| expect_agent_status |
| expect_alternate_plan |
| expect_appointment |
| expect_baths |
| expect_beds |
| expect_business_development |
| expect_call_availability |
| expect_company_name |
| expect_competitor_status |
| expect_confidence |
| expect_contact_confirmation |
| expect_contact_time |
| expect_contingency |
| expect_credit |
| expect_credit_score |
| expect_debt_to_income |
| expect_decision_maker |
| expect_delivery_followup |
| expect_description |
| expect_down_payment |
| expect_email |
| expect_employment_status |
| expect_equity_status |
| expect_financial_default |
| expect_financing_status |
| expect_first_time_buyer |
| expect_fsbo_reason |
| expect_garage_stalls |
| expect_image |
| expect_income |
| expect_interest |
| expect_is_local |
| expect_language |
| expect_lead_type |
| expect_listing_appointment |
| expect_living_space |
| expect_loan_balance |
| expect_location |
| expect_lot_size |
| expect_meeting_location |
| expect_military_active_duty |
| expect_military_branch |
| expect_military_discharge_type |
| expect_military_reserves_service |
| expect_military_service_term |
| expect_mortgage_escrow |
| expect_mortgage_intent |
| expect_motivation |
| expect_motivation_plans |
| expect_name |
| expect_outcome |
| expect_ownership |
| expect_ownership_timeline |
| expect_phone |
| expect_preferred_channel |
| expect_price |
| expect_prior_loan_experience |
| expect_problem |
| expect_product_interest |
| expect_promotional_offer |
| expect_property_feature |
| expect_property_location |
| expect_property_preferences |
| expect_property_records |
| expect_property_status |
| expect_property_type |
| expect_property_value |
| expect_question |
| expect_readiness |
| expect_relocating |
| expect_savings |
| expect_selling_address |
| expect_showing_appointment |
| expect_time |
| expect_timeframe |
| expect_url |
| expect_veteran |
| expect_veteran_service_disability |
Stages
| Name | Description |
|---|---|
| not_responded | The lead has not responded in this conversation. |
| responded | The lead has responded in this conversation. |
| not_interested | The lead has indicated no interest or opted out of communication in this conversation. |
| interested | The lead has responded and has not been classified as not interested. |
| needs_follow_up | The lead has reached a conclusion in the conversation that requires further follow-up. |
Domains
To use domains other than the default real_estate domain, the domains have to be enabled in the settings and an appropriate lead type has to be selected in the lead_type slot. An example of using the mortgage scripts for a new home loan buyer would be to set the allowedDomains
settings value to ["real_estate", "mortgage"]
and setting the lead_type slot to the values "buyer"
and "new_home_loan"
.
Conversation Webhooks
The Conversation Webhook is resource, that represents a url endpoint that will be called for certain actions called triggers. Examples of triggers include conversation updates, response creation, and fallback suggested. Each webhook belongs to an client/API key and all conversations created by that client will be linked to webhooks of the same client.
API Schemas
ConversationWebhook
| Field | Type | Description | Readable? | Writable? | Required? | Default |
|---|---|---|---|---|---|---|
| id | ObjectId |
The ID of the conversation webhook this resource represents. | Yes | No | No | |
| name | String |
The user friendly name of the webhook. Has no functional value but useful for describing the webhook's purpose. | Yes | Yes | No | |
| target | String |
A valid url that the webhook payload will be sent to. | Yes | Yes | Yes | |
| secret | String |
A secret key that will be used as a http header to ensure the sender is our system. | Yes | No | No | |
| version | String |
A string indicating the API version. (e.g. 'v1') | Yes | No | No | 'v1' |
| triggers | List<String> |
The list of triggers this webhook is subscribed to. | Yes | Yes | Yes | |
| createdAt | DateTime |
The datetime string of when this webhook was created. | Yes | No | No | |
| updatedAt | DateTime |
The datetime string of when this webhook was last updated. | Yes | No | No |
Webhook Schemas
ConversationSlotUpdate
| Field | Type | Description |
|---|---|---|
| name | String |
The name of the slot being updated. |
| action | String |
The action to take on the slot. Either 'set' or 'push' for scalar or list types respectively. |
| value[1] | Any [2] |
The new value being set for this slot. Only exists if the action is 'set' . |
| values[1] | List<Any> [2] |
The list of values being added to current list of values for this slot. Only exists if the action is 'push' . |
ConversationStageUpdate
| Field | Type | Description |
|---|---|---|
| name | String |
The name of the stage that is being added or removed from the stage list. |
| action | String |
The action to take for this stage. Will be either 'add' or 'remove' . |
| reasons | List<String> |
A list of reasons why this stage occurred. A list of either intent names or slot comparisons. |
ConversationUpdates
| Field | Type | Description |
|---|---|---|
| slots | List<ConversationSlotUpdate> [^] |
Conversation slot updates. |
| stages | List<ConversationStageUpdate> [^] |
Conversation stage updates. |
value
andvalues
are mutually exclusive. Only one will exist at a time and the other will be undefined.- See slots for more info on each slot and it's type.
Conversation Webhook Overview
Webhooks are used to receive updates for conversations available on the API. These updates are used to notify when a conversations state has changed or when an action like sending a response should be taken. To use webhooks, create a webhook with the triggers that you want to listen for and the target set to an endpoint you control in your system.
Response Created
Response Created Example
{
"trigger": "response:created",
"id": "5c09a4416241ea2c293275b8",
"response": {
"text": "Can you tell me more about the location you're interested in?"
}
}
Trigger
response:created
Description
This trigger is called when a new response for a conversation has been created. Responses are generated by Structurely for a message added to the relevant conversation. Use this event to know when and what to respond to a lead with after a lead sends a message.
Payload
| Parameter | Type | Description |
|---|---|---|
| trigger | String |
The trigger that triggered this webhook. |
| id | ObjectId |
The id of the conversation. |
| response | Message [^] |
A truncated Message object containing only the text field. The text was generated by Structurely to be sent as a response to a message created in this conversation. |
Conversation Updated
Conversation Updated Example
{
"trigger": "conversation:updated",
"id": "5c09a4416241ea2c293275b8",
"updates": {
"slots": [
{
"name": "email",
"action": "set",
"value"<EMAIL_ADDRESS>},
{
"name": "address",
"action": "push",
"values": ["123 Main St.", "456 North Ave."]
}
],
"stages": [
{
"name": "not_responded",
"action": "remove",
"reasons": []
},
{
"name": "responded",
"action": "add",
"reasons": []
},
{
"name": "needs_follow_up",
"action": "add",
"reasons": ["financing_status is false"]
}
]
}
}
Trigger
conversation:updated
Description
This trigger is called when the convsersation object is updated. It will include the updates to the slots and stages. Use this to maintain state between your system and the Structurely API without polling.
Payload
| Parameter | Type | Description |
|---|---|---|
| trigger | String |
The trigger that triggered this webhook. |
| id | ObjectId |
The id of the conversation. |
| updates | ConversationUpdates [^] |
The updates to the conversation stages and slots. |
List Conversation Webhooks
curl 'https://api.structurely.com/v1/conversationWebhooks?name=My%20&trigger=response:created' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"_metadata": {
"collection": "conversationWebhooks",
"limit": 10,
"offset": 0,
"total": 2
},
"conversationWebhooks": [
{
"id": "5ceec43ce1b5b412ba9d0e73",
"name": "My Webhook",
"target": "https://www.example.com/webhooks/endpoint",
"secret": "nLjs7uu5AvQfTjqXpXHnSOfj0h8bvc0w0eeZNWgFR1pJo9Gb",
"version": "v1",
"triggers": ["conversation:updated", "response:created"],
"updatedAt": "2019-05-29T12:41:16.000Z",
"createdAt": "2019-05-29T12:41:16.000Z"
},
{
"id": "5ceed39ce1b5b412ba9d0e74",
"name": "My Other Webhook",
"target": "https://hooks.example.com/structurely/response_created",
"secret": "ZQjevvm3JW7Y8drTROfoRokuYR75BPpAq7NDj0MYkQS2pQVa",
"version": "v1",
"triggers": ["response:created"],
"updatedAt": "2019-05-29T13:48:20.000Z",
"createdAt": "2019-05-29T13:48:20.000Z"
}
]
}
This endpoint returns all webhooks that match the provided parameters. The objects returned will match all the provided parameters.
HTTP Request
GET https://api.structurely.com/v1/conversationWebhooks
Query Parameters
| Parameter | Type | Description | Required? | Default |
|---|---|---|---|---|
| limit | Integer[1,100] |
The number of results to return | No | 10 |
| offset | Integer[0,) |
Indicates the number of results to skip | No | 0 |
| sort[1] | String |
A comma separated list of fields to sort by | No | -createdAt |
| name[2] | String |
A partial or full name of a webhook to search | No | None |
| target | String |
A exact URL target of a webhook to match | No | None |
| trigger | String |
An exact trigger that must be in a matched webhooks triggers list. Matched webhooks must include this trigger exactly. Matched webhooks may include other triggers. | No | None |
- The sort string allows multiple fields with left to right precedence with optional
-
or+
for controlling ascending and descending order - String search fields use a case insensitive partial filter that can match any part of the string unless otherwise noted
Create Conversation Webhook
curl 'https://api.structurely.com/v1/conversationWebhooks' \
-X POST \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "name": "My Webhook", "target": "https://www.example.com/webhooks/endpoint", "triggers": ["conversation:updated", "response:created"] }'
The above command returns JSON structured like this:
{
"id": "5ceec43ce1b5b412ba9d0e73",
"name": "My Webhook",
"target": "https://www.example.com/webhooks/endpoint",
"secret": "nLjs7uu5AvQfTjqXpXHnSOfj0h8bvc0w0eeZNWgFR1pJo9Gb",
"version": "v1",
"triggers": ["conversation:updated", "response:created"],
"updatedAt": "2019-05-29T12:41:16Z",
"createdAt": "2019-05-29T12:41:16Z"
}
This endpoint creates and returns a new conversation webhook.
HTTP Request
POST https://api.structurely.com/v1/conversationWebhooks
Body Parameters[^]
| Parameter | Type |
|---|---|
| name | String |
| target | String |
| triggers | List<String> |
Get Conversation Webhook
curl 'https://api.structurely.com/v1/conversationWebhooks/5ceec43ce1b5b412ba9d0e73' \
-H 'X-Api-Authorization: myapikey'
The above command returns JSON structured like this:
{
"id": "5ceec43ce1b5b412ba9d0e73",
"name": "My Webhook",
"target": "https://www.example.com/webhooks/endpoint",
"secret": "nLjs7uu5AvQfTjqXpXHnSOfj0h8bvc0w0eeZNWgFR1pJo9Gb",
"version": "v1",
"triggers": ["conversation:updated", "response:created"],
"updatedAt": "2019-05-29T12:41:16Z",
"createdAt": "2019-05-29T12:41:16Z"
}
HTTP Request
GET https://api.structurely.com/v1/conversationWebhooks/<id>
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation webhook to retrieve |
Update Conversation Webhook
curl 'https://api.structurely.com/v1/conversationWebhooks/5ceec43ce1b5b412ba9d0e73' \
-X PATCH \
-H 'X-Api-Authorization: myapikey' \
-H 'Content-Type: application/json' \
-d '{ "name": "My Cool Webhook", "target": "https://hooks.example.com/structurely/conversation_updated", "triggers": ["conversation:updated"] }'
The above command returns JSON structured like this:
{
"id": "5ceec43ce1b5b412ba9d0e73",
"name": "My Cool Webhook",
"target": "https://hooks.example.com/structurely/conversation_updated",
"secret": "nLjs7uu5AvQfTjqXpXHnSOfj0h8bvc0w0eeZNWgFR1pJo9Gb",
"version": "v1",
"triggers": ["conversation:updated"],
"updatedAt": "2019-05-29T12:41:16Z",
"createdAt": "2019-05-29T12:41:16Z"
}
HTTP Request
PATCH https://api.structurely.com/v1/conversationWebhooks/<id>
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation webhook to update |
Body Parameters[^]
| Parameter | Type |
|---|---|
| name | String |
| target | String |
| triggers | List<String> |
Delete Conversation Webhook
curl 'https://api.structurely.com/v1/conversationWebhooks/5ceec43ce1b5b412ba9d0e73' \
-X DELETE
-H 'X-Api-Authorization: myapikey'
The above command returns an empty response with the status 204 if successful
HTTP Request
DELETE https://api.structurely.com/v1/conversationWebhooks/<id>
URL Parameters
| Parameter | Description |
|---|---|
| id | The ID of the conversation webhook to delete |
Errors
The Structurely API uses the following error codes:
| Error Code | Meaning |
|---|---|
| 400 | Bad Request -- Your request was invalid. |
| 401 | Unauthorized -- No API key provided. |
| 403 | Forbidden -- Your API key is invalid. |
| 404 | Not Found -- The specified resource could not be found. |
| 405 | Method Not Allowed -- You tried to access an endpoint with an invalid method. |
| 500 | Internal Server Error -- We had a problem with our server. Try again later. |
| 502 | Bad Gateway -- Our backend services are unavailable. Please try again later. |
| 503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |
| 504 | Gateway Timeout -- Our backend services are taking too long to respond. Please try again later. |


tRonk Movies
Title:
Description:
Movie Actors:
Release Date:
Copies:
Action
Adventure
Comedy
Crime
Drama
Thriller
Romance
Save Movie
Delete Movie
Borrow Movie
Return Movie


@TheCryptoDog @cryptoritual @DeFiDaJo Hey @TheCryptoDog Are you able to attend #Hedera18? If not, you don't want to miss our free livestream! You can register here https://t.co/wnRpYhPqIo
Show Epicenter - Learn about Blockchain, Ethereum, Bitcoin and Distributed Technologies, Ep Mance Harmon: Hashgraph – A Radically Novel Consensus Algorithm - Jan 25, 2018


Anastasia Sorkin is an independent web developer who is passionate about bringing client’s visions to life. Her strongest skill is creativity, being able to gather client's requirements and translate those into an engaging, effective and unique website is what motivates her.
Anastasia is also a goal oriented innovative entrepreneur and a passionate marketer with tactful and diplomatic communication skills. Her spectrum of unique skills makes Anastasia a solid competitor in the modern, fast-growing marketing industry. She successfully initiated, led and managed teams and projects that greatly exceeded all expectations.


Observable
@interface Observable : NSObject
An object that emits events.
Listeners can bind to specific events and be notified when the event is triggered.
-
A dictionary that contains all methods to be executed when an event is triggered
Declaration
Objective-C
@property (readwrite, strong, nonatomic) NSMutableDictionary *_Nonnull callbacks;
Swift
var callbacks: NSMutableDictionary { get set }
-
Binds to an event by providing a block that will receive the event payload as a parameter.
The block will be executed synchronously, for costly operations prefer the use of bindSync:callback:.
Declaration
Objective-C
- (nonnull Callback)bind:(nonnull NSString *)event callback:(nonnull void (^)(NSDictionary *_Nonnull))callback;
Swift
func bind(_ event: String, callback: @escaping ([AnyHashable : Any]) -> Void) -> Callback
Parameters
event
Name of the event to bind to
callback
Block to be executed synchronously when the event is triggered
Return Value
Returns the callback instance created, to be used when unbinding from the event
-
Binds to an event by providing a block that will receive the event payload as a parameter.
The block will be executed synchronously, for costly operations prefer the use of bindSync:callback:.
Declaration
Objective-C
- (nonnull Callback)bindSync:(nonnull NSString *)event callback:(nonnull void (^)(NSDictionary *_Nonnull))callback;
Swift
func bindSync(_ event: String, callback: @escaping ([AnyHashable : Any]) -> Void) -> Callback
Parameters
event
Name of the event to bind to
callback
Block to be executed synchronously when the event is triggered
Return Value
Returns the callback instance created, to be used when unbinding from the event
-
Binds to an event by providing a block that will receive the event payload as a parameter and return a Promise that will be resolved asynchronously.
Declaration
Parameters
event
Name of the event to bind to
callback
Block to be executed when the event is triggered
Return Value
Returns the provided callback, to be used when unbinding from the event
-
Unbinds the provided callback from an event.
Declaration
Objective-C
- (void)unbind:(nonnull NSString *)event callback:(nonnull Callback)callback;
Swift
func unbind(_ event: String, callback: @escaping Callback)
Parameters
event
The name of the event
callback
The callback that was returned when the bind method was called.
-
Triggers the event by calling all its bound callbacks with args as parameters.
have finished processing the triggered event
Declaration
Objective-C
- (nonnull Promise *)trigger:(nonnull NSString *)event args:(NSDictionary *_Nullable)args;
Swift
func trigger(_ event: String, args: [AnyHashable : Any]?) -> Promise
Parameters
event
The name of the event to be triggered
args
The payload of the event, to be passed to the callbacks
Return Value
Returns a promise that will be resolved when all of the callbacks
-
Triggers the event by calling all its bound callbacks.
have finished processing the triggered event
Declaration
Objective-C
- (nonnull Promise *)trigger:(nonnull NSString *)event;
Swift
func trigger(_ event: String) -> Promise
Parameters
event
The name of the event
Return Value
Returns a promise that will be resolved when all of the callbacks


src/lib/sub-collection-writer.ts
The ability to place docs and collection n deep but also flatten the it in order to reduce reads. It becomes a balance between speed and economy. Since multiple docs can be read simultaneously but will cost more. These classes aim to make it easy to control that.
Allows you to have a complex deep object and write it to firestore by splitting it up in to collections and documents.
Example services object that we wish to save to firestore.
const services = {
name: 'example services',
address: {
zipcode: 12345,
city: 'example city',
line1: '12 example rd'
},
dishes: [
{
name: 'dish1',
images: [
{url: example.jpg},
{url: example2.jpg}
]
},
{
name: 'dish2',
images: [
{url: example.jpg},
{url: example2.jpg}
]
}
]
reviews: [
{
score: 5
text: 'decent food'
},
{
score: 8
text: 'good food'
},
]
}
You would be able to save this data 'as is' to a single firestore document using arrays and maps. The problem comes when you later on wish to add/delete or alter an image of dish.
Another issue is that you might have thousands of reviews and since they are all saved in the same document. If for example you wish to show a list of all restaurants and all you want to show is the name before a user clicks the services you would still have to download the entire services object containing all those thousands of reviews. This would be ok in terms of cost of reads but very expensive in terms of performance. Each services object would be huge, killing the user's data plan and slowing down your site.
It would be much better to make reviews a collection inside services. That way you could show the services name without downloading all the reviews. If you wish to show an average review score the most efficient way would be to to calculate that each time you update the review collection and adding the average to the services document.
What this wrapper intends to do is to simplify saving some data in sub collections without changing the way you work with the data. So you could have a services object that contains all the data and when you add it to firestore the data is automatically placed in your sub collections without you having to worry about it after you initially set it up.
Another huge advantage to separating your data in to sub collections is that it allows you to choose between performance and cost. Saving the data to one large document would save your firestore read/writes and could potentially make a big difference in terms of cost depending on your application. But it would also slow it down as explained above. Splitting your data up in to sub collections allows you to asyncronously read/write those collections at the same time.
So if you compare one large document and a small document with 4 subcollections of about equal size. It would require 5 firestore reads instead of 1 if each sub collection contains 1 document. But the speed could also potentially be 5X faster since all those parts are read at the same time.
Using SubCollectionWriters and SubCollectionQueries allows you to create the perfect compromise between ease of working with the firestore database, cost and performance.
const subCollectionWriters: SubCollectionWriter[] = [
{ name: 'data' },
{
name: 'images',
docId: 'data', // images is an array but since a docId is given it be saved in a single doc
},
{
name: 'variants',
subCollectionWriters: [ // sub collection inside a sub collection
{ name: 'otherData'}
]
}
];
Properties |
|
| Optional docId |
Type : string
|
|
Defined in src/lib/sub-collection-writer.ts:109
|
|
if the data to be written is an array and a docId is given the array is saved as single document under that docId. if not docId is given the array will be saved as individual documents with random names. if no docId is given and the data is an object a single document will be created using a default name i.e this.defaultDocId |
| Optional isFlat |
Type : boolean
|
Default value : false
|
|
Defined in src/lib/sub-collection-writer.ts:117
|
|
if true then the next level subCollectionWriters will be placed at the same level as this with a reference back to the linked data, good for secure subcols |
| name |
Type : string
|
|
Defined in src/lib/sub-collection-writer.ts:102
|
|
the name of the subCollection to be created. If a key in the data to be written is the same as this name it will be saved separately in a sub collection. |
| Optional subCollectionWriters |
Type : SubCollectionWriter[]
|
|
Defined in src/lib/sub-collection-writer.ts:112
|
|
each collection can contain other sub collections |
export class SubCollectionWriter {
/** the name of the subCollection to be created. If a key in the data to be written is the same as this name it will be
* saved separately in a sub collection.
*/
name: string;
/** if the data to be written is an array and a docId is given the array is saved as single document under that docId.
* if not docId is given the array will be saved as individual documents with random names.
* if no docId is given and the data is an object a single document will be created using a default name
* i.e this.defaultDocId
*/
docId?: string;
/** each collection can contain other sub collections */
subCollectionWriters?: SubCollectionWriter[]; // sub/sub collections
/** if true then the next level subCollectionWriters will be placed at the same level as this with a reference back
* to the linked data, good for secure subcols
*/
isFlat?: boolean = false;
}


Honda HRU19D Lawnmower Full Service (Carburettor, Oil, Spark Plugs, Blades)
My Honda HRU19D has gone 10 years without a service.
The closest manual I could find is the one for the HRU19K1. While there are lots of good videos on this (such as eReplacementParts.com, Steve’s Small Engine Saloon and Bruce Pender), for those of us that prefer to read, here are step by step instructions.
In the past year, this mower has become hard to start. Needs a carby clean and while I’m at it, might as well service everything.
Carburettor and Air Filter
Step 1 Air filter
Shut off the fuel valve on the hose that runs into the carby. Take off the air filter cover and the 2x 10mm bolts that go into the engine. Examine air filter and replace if bad.
Step 2 Fuel Hose
Undo the hose underneath (fuel line). You need to pull the retaining clip out of the way with pliers and then slide off the hose.
Step 3 Linkages
Tilt the carby and undo the 3 linkages.
Step 4 Remove carby
It should come out now. It’s pretty dirty.
At this point I should have removed the front and read gaskets but I did this in the middle of Step 6.
Step 5 Float Bowl
Turn it upside down and undo the 10mm nut. Remove the bowl.
Step 6 Float
Remove the float pin and then the float.
It is at this point I removed the front and rear gaskets.
Don’t lose the float valve that attaches to the float.
Step 7 Main Jet
Using a flat blade screwdriver, unscrew the main jet and tap the size of the carby until it comes out..
Step 8 Main Nozzle
After some more tapping the main nozzle should come out.
Step 9 Clean
Everything looked relatively clean. I didn’t want to mess with the idle screw and clean the pilot jet because it affects idle and not my starting problem (see for how to do this eReplacementParts.com).
Clean everything with carburettor cleaner, paying particular attention to the air flow and fuel flow paths indicated in the figure below.
Step 10 Put Back Together
Put everything back together.
Oil Change
Step 1 Check Oil
Remove the dip stick, check the oil level and look at the colour of the oil. Mine had not been used much the previous summer and looked good so I’ll change it next year.
Step 2 Change oil
If you need to change the oil, do so when it is warm. Close the fuel valve and tip the oil out at the dipstick opening. Use SAE 10W-30 4 stroke oil.
Spark Plugs
Step 1 Remove Cable
Remove spark plug cable.
Step 2 Remove Plug
Remove spark plug. It is a NGK BPR5ES.
Socket is 13/16”.
Step 3 Check Plug
Examine electrode, looks good.
Gap is supposed to be 0.7-0.8 mm so let’s go with 0.75 mm.
Step 4 Put Back Together
Put everything back. Don’t overtighten.
Blade replacement
Step 1 Remove Cable
Remove spark plug cable (so engine can’t start on you).
Step 2 Turn on Side and Remove Blade Disc
Turn off the fuel valve and turn on its side with the air filter facing up. Use a block of wood to wedge the blade so it won’t turn. Using a 14 mm socket, undo the nut for the blade disc.
Step 3 Examine blade
Mine were in bad shape.
The part number for 4x the normal height blades is 06720-VK0-600. It took me a while to find this handy table.
I purchased new blades from Online Mower Spares who I highly recommend.
Step 4 Remove blade nuts
These were 17 mm.
Step 5 Clean
I used a wire brush to clean the blade disc.
Step 6 Attach New Blades
One thing that I didn’t know is that the blades are not perpendicular to the disc. They are at a slightly acute angle. If you make them perpendicular, they hit the side of the mower (only found out after I put everything back together). I used the shadow of the old blade for alignment.
Step 7 Put Back Together
Put the cutter disc back on the mower. Replace the spark plug cable and open the fuel valve.
Try it Out
Works like new now. Since the main jet and main nozzle looked clean, I suspect the problem was the float not moving properly so either the pin or the seat. The mower now starts easily and cuts cleanly. Even the sound is different from having cleaned off the caked-on grass.


The top 10 most common items are:


A common supertype for companion classes of primitive types.
For example, in the following code
This class exists only as a dummy subclass so that there are two ambiguous implicit conversions from Unit to some subclass to Object.
A object representing 'object scala.
A object representing 'object scala.
A object representing 'object scala.
A object representing 'object scala.
A object representing 'object scala.
A object representing 'object scala.
A object representing 'object scala.
A object representing 'object scala.
A object representing 'object scala.


For a domain object that you cannot or do not want to modify, use the PdxSerializer
class to serialize and deserialize the object’s fields. You use one PdxSerializer
implementation for the entire cache, programming it for all of the domain objects that you handle in this way.
With PdxSerializer
, you leave your domain object as-is and handle the serialization and deserialization in the separate serializer. You register the serializer in your cache PDX configuration. Program the serializer to handle all of the domain objects you need.
If you write your own PdxSerializer
and you also use the ReflectionBasedAutoSerializer
, then the PdxSerializer
needs to own the ReflectionBasedAutoSerializer
and delegate to it. A Cache can only have a single PdxSerializer
instance.
Note:
The PdxSerializer
toData
and fromData
methods differ from those for PdxSerializable
. They have different parameters and results.
Procedure
In the domain classes that you wish to PDX serialize, make sure each class has a zero-arg constructor. For example:
public PortfolioPdx(){}
If you have not already implemented
PdxSerializer
for some other domain object, perform these steps:Create a new class as your cache-wide serializer and make it implement
PdxSerializer
. If you want to declare your new class in thecache.xml
file, have it also implementDeclarable
.Example:
import org.apache.geode.cache.Declarable; import org.apache.geode.pdx.PdxReader; import org.apache.geode.pdx.PdxSerializer; import org.apache.geode.pdx.PdxWriter; public class ExamplePdxSerializer implements PdxSerializer, Declarable { ...
In your cache pdx configuration, register the serializer class in the cache’s
<pdx>
<pdx-serializer>
<class-name>
attribute.Example:
// Configuration setting PDX serializer for the cache <cache> <pdx> <pdx-serializer> <class-name>com.company.ExamplePdxSerializer</class-name> </pdx-serializer> </pdx> ... </cache>
Or use the
CacheFactory.setPdxSerializer
API.Cache c = new CacheFactory .setPdxSerializer(new ExamplePdxSerializer()) .create();
Note: You cannot specify a custom
pdx-serializer
class using gfsh, however theconfigure pdx
command automatically configures the org.apache.geode.pdx.ReflectionBasedAutoSerializer class. See configure pdx.Program
PdxSerializer.toData
to recognize, cast, and handle your domain object:- Write each standard Java data field of your domain class using the
PdxWriter
write methods. - Call the
PdxWriter
markIdentityField
method for each field you want to have Geode use to identify your object. Put this after the field’s write method. Geode uses this information to compare objects for operations like distinct queries. If you do not set as least one identity field, then theequals
andhashCode
methods will use all PDX fields to compare objects and consequently, will not perform as well. It is important that the fields used by yourequals
andhashCode
implementations are the same fields that you mark as identity fields. - For a particular version of your class, you need to consistently write the same named field each time. The field names or number of fields must not change from one instance to another for the same class version.
- For best performance, do fixed width fields first and then variable length fields.
- If desired, you can check the portability of the object before serializing it by adding the
checkPortability
parameter when using thePdxWriter
writeObject
,writeObjectArray
, andwriteField
methods.
Example
toData
code:public boolean toData(Object o, PdxWriter writer) { if(!(o instanceof PortfolioPdx)) { return false; } PortfolioPdx instance = (PortfolioPdx) o; writer.writeInt("id", instance.id) //identity field .markIdentityField("id") .writeDate("creationDate", instance.creationDate) .writeString("pkid", instance.pkid) .writeObject("positions", instance.positions) .writeString("type", instance.type) .writeString("status", instance.status) .writeStringArray("names", instance.names) .writeByteArray("newVal", instance.newVal) return true; }
Program
PdxSerializer.fromData
to create an instance of your class, read your data fields from the serialized form into the object’s fields using thePdxReader
read methods, and return the created object.Provide the same names that you did in
toData
and call the read operations in the same order as you called the write operations in yourtoData
implementation.Geode provides the domain class type and
PdxReader
to thefromData
method.Example
fromData
code:public Object fromData(Class<?> clazz, PdxReader reader) { if(!clazz.equals(PortfolioPdx.class)) { return null; } PortfolioPdx instance = new PortfolioPdx(); instance.id = reader.readInt("id"); instance.creationDate = reader.readDate("creationDate"); instance.pkid = reader.readString("pkid"); instance.positions = (Map<String, PositionPdx>)reader.readObject("positions"); instance.type = reader.readString("type"); instance.status = reader.readString("status"); instance.names = reader.readStringArray("names"); instance.newVal = reader.readByteArray("newVal"); return instance; }
- Write each standard Java data field of your domain class using the
If desired, you can also enable extra validation in your use of
PdxWriter
. You can set this by setting the system propertygemfire.validatePdxWriters
to true. Note that you should only set this option if you are debugging new code as this option can decrease system performance.


Prawn Markup Showcase
Text features
paragraphs are nicely separated from each other.
Margin is or will be customizable at some point.
Strong or emphasized formatting as well as
links are supported.
and horizontal lines!
Table features
Also tables are nice:
| No | Description | State |
| 1 | Headers and custom widths are supported | Done |
| 2 | | Done |
| 3 | Even lists - one
- two
| Check |
| 4 | and Images: | Yieha |
This table has text underneath
List features
Unordered
Here may be text, too
- Lorem ipsum doler sit amet. Lorem ipsum doler sit amet. Lorem ipsum doler sit amet. Lorem ipsum doler sit amet. Lorem ipsum doler sit amet. Lorem ipsum doler sit amet.
- anything
Ordered
- Lorem ipsum doler sit amet. Lorem ipsum doler sit amet. Lorem ipsum doler sit amet. Lorem ipsum doler sit amet. Lorem ipsum doler sit amet. Lorem ipsum doler sit amet.
- anything
So far
and thanks for all the fish


TPSTAT.SYS
TPSTAT.SYS (\FBB\SYSTEM)
This file holds the statistics of the rubrics. Deleting it will
restart these statistics from scratch. Do not delete the file
while the BBS is running. You will be prompted to create it
when booting the software.
The file is organized as 21 records.
Each record is a long integer holding the number of seconds used
for the current record. Each record correspond to the level
(first number of the three numbers of the status bar).
record 0 : Server menu
record 1 : Message (sending or receiving)
record 2 : Qra locator
record 3 : Statistics
record 4 : Documentations
record 5 : Nomenclature
record 6 : Trajectography
record 7 : Unused
record 8 : Sending bin message
record 9 : FbbDOS menu
record 10 : Gateway
record 11 : Modem
record 12 : Binary transfer
record 13 : X forwaring
record 14 : Mailbox usage
record 15 : Forwarding
record 16 : Console chat
record 17 : YAPP
record 18 : Conference
record 19 : Editor
record 20 : Themas area
This page was last updated


Search Results (from `./source/_includes/custom/lunr-search/entries.html/`)
This line appears inside of the "entries" div in `source/_includes/custom/lunr-search/entries.html`.
This file
(source/_includes/custom/lunr-search/entries.html)
contains search entries.
And this cluster of lines appears outside the "entries" div.