Skip to content

Commit

Permalink
[DOCS-468] document child install limits (#604)
Browse files Browse the repository at this point in the history
* [DOCS-468] document child install limits

* incorporate review feedback.

* Remove redundancies.
  • Loading branch information
jimmyjames authored Apr 20, 2017
1 parent cef57c9 commit b16db96
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 54 deletions.
121 changes: 74 additions & 47 deletions ratelimits/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,91 +6,118 @@ Rate Limits

Rate limiting ensures that no single SmartApp or Device Handler will consume too many shared resources.

Rate limits apply to SmartApps, Device Handlers, and Web Services SmartApps.
Rate limits apply to **all** SmartApps and Device Handlers.

-----

SmartApp and Device Handler rate limits
---------------------------------------

SmartApps and Device Handlers are monitored for excessive resource utilization on two measures: **Execution Time Limits** and **Execution Count Limits.**
SmartApps and Device Handlers are monitored for excessive resource utilization on two measures: *Execution count limits* and *Execution time limits*.

Execution time limits
^^^^^^^^^^^^^^^^^^^^^
Execution count limits
^^^^^^^^^^^^^^^^^^^^^^

- Methods are limited to a continuous execution time of 20 seconds.
- SmartApps are limited to a total continuous execution time of 40 seconds.
- Device Handlers are limited to a total continuous execution time of 40 seconds.
SmartApps and Device Handlers are subject to the following execution count limits.
These limits are per *installed SmartApp or Device Handler*.

If these limits are exceeded, the current execution will be suspended.
===================== =========== ===========
Execution count limit Time window Description
===================== =========== ===========
250 executions 60 seconds A maximum of 250 executions per minute is allowed for each installed SmartApp or Device Handler.
===================== =========== ===========

Execution count limits
^^^^^^^^^^^^^^^^^^^^^^
If the limit is exceeded, an error will be displayed in Live Logging, and no further executions for this installed SmartApp or Device Handler will occur until the current 60-second time window expires.

A SmartApp or a Device Handler is limited to no more than 250 executions in 60 seconds. If the limit of 250 executions is reached in a 60-second time window, no further executions will occur until the next time window. A log entry will be created for the SmartApp or the Device Handler that was rate limited. The count will start over when the current time window closes and the next time window begins.
Execution time limits
^^^^^^^^^^^^^^^^^^^^^

Ways to avoid hitting rate limits
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
These execution time limits apply to SmartApps and Device Handlers:

A common cause for exceeding the 250 executions within 60 seconds limit is excessive subscriptions that might result in an infinite loop of events. For example, subscribing to an “on” and “off” Event and the “on” command triggers the “off” Event and vice versa - leading to a never-ending chain of event handlers being called. It is also possible that a SmartApp that subscribes to a very large number of particularly “chatty” devices may run into this limit. Making sure that your SmartApp subscriptions are not excessive in number will help avoid hitting the rate limit.
=============================== =====
What Limit
=============================== =====
Method execution time 20 seconds
Total continuous execution time 40 seconds
=============================== =====

Similarly, a Device Handler may exceed Rate Limit when it sends many commands to one device by receiving a large number of Event subscriptions (if that doesn’t first hit the limit for SmartApps). For example, DLNA players that are extremely chatty, or devices that bind to frequently changing energy/power values may also encounter this limit. Ensure that your Device Handler does not issue too many commands to one single device in a single 60-second time window.
If these limits are exceeded, the current execution will be suspended.

----

.. _web_services_rate_limiting:

Web services SmartApps rate limits
----------------------------------
Web services rate limit headers
-------------------------------

SmartApps or Device Handlers that expose their web services APIs are limited to receiving 250 requests in a single 60-second time window.
SmartApps and Device Handlers that expose RESTful APIs are subject to the same rate limits as documented above.
The SmartThings platform will set three HTTP headers on the response for every inbound API call, so that a client may understand the current rate limit status.

There are various headers available on every request that provide information about the current rate limit limits for a given installed SmartApp or Device Handler. These are discussed further below.
======================= ===========
Header Description
======================= ===========
``X-RateLimit-Limit`` The total enforced rate limit (250)
``X-RateLimit-Current`` The number of executions within the current rate limit time window, for this installed SmartApp or Device Handler.
``X-RateLimit-TTL`` The time remaining (in seconds) before the current rate limit window resets, for this installed SmartApp or Device Handler.
======================= ===========

If the rate limit is exceeded, the following response is sent to the client:

Rate limit headers
^^^^^^^^^^^^^^^^^^
=========================== ===============================================================================================================
HTTP Response Code Error Response
=========================== ===============================================================================================================
``429 (Too Many Requests)`` ``{"error": true, "type": "RateLimit", "message": "Please try again later"}``
=========================== ===============================================================================================================

The SmartThings platform will set three HTTP headers on the response for every inbound API call, so that a client may understand the current rate limiting status:
----

*X-RateLimit-Limit: 250*
The rate limit - in this example, the limit is 250 requests.
.. _sms_rate_limits:

*X-RateLimit-Current: 1*
The current count of requests for the given time window. In this example, there has been one request within the current rate limit time window.
SMS rate limits
---------------

*X-RateLimit-TTL: 58*
The time remaining in the current rate limit window. In this example, there is 58 seconds remaining before the current rate limit window resets.
The following limits apply to sending SMS messages:

========================================== ===========
Limit If exceeded
========================================== ===========
15 SMS messages per number, per 60 seconds No additional SMS messages will be sent until the next minute.
========================================== ===========

Rate limit HTTP status code
^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. note::

In addition to the three HTTP headers above, when the rate limit has been exceeded, the HTTP status code of 429 will be sent on the response, as shown below.
This limit applies **per number**, not per SmartApp or user.

----

Rate limit error handling
^^^^^^^^^^^^^^^^^^^^^^^^^
.. _parent_child_count_limit:

The following error may be returned by the SmartThings platform when a Rate Limit is hit:
Parent-child relationship limit
-------------------------------

=========================== =============================================================================================================== =====
HTTP Response Code Error Message Cause
=========================== =============================================================================================================== =====
``429 (Too Many Requests)`` {"error": true, "type": "RateLimit", "message": "Please try again later"} The rate limit for this SmartApp installation has been exceeded.
=========================== =============================================================================================================== =====
The number of child SmartApps or child devices that a SmartApp or Device Handler may have are subject to the following limits:

----
=================== ===========
Maximum child count Description
=================== ===========
500 A SmartApp may have at most a combination of 500 child SmartApps or Devices. A Device Handler may have at most 500 child Devices.
=================== ===========

.. _sms_rate_limits:
If this limit is exceeded, an exception is thrown and will be displayed in Live Logging.
If initiated from within the mobile app, an error will be seen in the mobile application as well.

SMS rate limits
---------------
----

No more than 15 SMS messages may be sent to the same number per minute.
Avoiding rate limits
--------------------

If this limit is exceeded, no additional SMS messages will be sent until the next minute.
While SmartThings rate limits are quite high compared to other service platforms, the event-driven nature of SmartThings can result in SmartApps or Device Handlers that may (unintentionally) reach this limit.
It is important to reason carefully about your code, think of worst-case scenarios, and monitor Live Logging when testing to reduce the liklihood of being rate limited.

.. note::
Here are some common pitfalls to watch out for:

This limit applies **per number**, not per SmartApp or user.
- A SmartApp may subscribe to a large number of "chatty" devices, causing the execution limit to be reached. For example, DLNA devices may be particularly chatty, and frequently changing energy/power values may cause the rate limit to be exceeded.
- Service Manager SmartApps that may be called by their child devices may reach the execution limit, if there are a number of child devices and/or they call the parent in response to frequent events.
- Synchronous (blocking) HTTP requests may hit the execution time rate limit, depending on the third party response time. Avoid this possibility by using :ref:`async_http_guide`.
- It's possible to create an infinite loop of events. For example, subscribing to both "on" and "off" events, and the "on" command triggers the "off" event and vice versa - leading to a never-ending chain of event handlers being called.
- Pay attention to any looping logic around creating child devices or SmartApps. Any error in the looping logic might result in creating too many children, which could encounter the parent-child limit.
6 changes: 6 additions & 0 deletions ref-docs/device-handler-ref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ An example use is in a composite device Device Handler.

A parent may have multiple children, but only one level of children is allowed (i.e., if a device has a parent, it may not have children itself).

.. warning::

A parent may have at most 500 children.


**Signature:**
``DeviceWrapper addChildDevice(String typeName, String deviceNetworkId, hubId, Map properties)``
Expand Down Expand Up @@ -177,6 +181,8 @@ A parent may have multiple children, but only one level of children is allowed (

``ValidationException`` - If the this device already has a parent.

``SizeLimitExceededException`` - If this device already has the maximum number of children allowed (500).

**Example:**

.. code-block:: groovy
Expand Down
39 changes: 32 additions & 7 deletions ref-docs/smartapp-ref.rst
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ addChildApp()

Adds a child app to a SmartApp.

.. warning::

A SmartApp may have a maximum of 500 child SmartApps and devices, combined.

**Signature:**
``InstalledSmartApp addChildApp(String namespace, String smartAppVersionName, String label, Map properties)``

Expand All @@ -224,16 +228,28 @@ Adds a child app to a SmartApp.
**Returns:**
:ref:`installed_smart_app_wrapper` - The InstalledSmartAppWrapper instance that represents the child SmartApp that was created.

**Throws:**
``IllegalArgumentException`` - If the label is not provided.

``NotFoundException`` - If the SmartApp cannot be found.

``SizeLimitExceededException`` - If this SmartApp already has the maximum number of children allowed (500).


addChildDevice()
----------------

Adds a child device to a SmartApp. An example use is in service manager SmartApps.
Adds a child device to a SmartApp.
An example use is in Service Manager SmartApps.

.. warning::

A parent may have at most 500 children.

**Signature:**
``DeviceWrapper addChildDevice(String namespace, String typeName, String deviceNetworkId, hubId, Map properties)``
``DeviceWrapper addChildDevice(String typeName, String deviceNetworkId, hubId, Map properties)``

**Throws:**
``UnknownDeviceTypeException``
``DeviceWrapper addChildDevice(String namespace, String typeName, String deviceNetworkId, hubId, Map properties)``

**Parameters:**
`String`_ ``namespace`` - the namespace for the device. Defaults to ``installedSmartApp.smartAppVersionDTO.smartAppDTO.namespace``
Expand All @@ -247,7 +263,14 @@ Adds a child device to a SmartApp. An example use is in service manager SmartApp
`Map`_ ``properties`` *(optional)* - A map with device properties.

**Returns:**
``DeviceWrapper`` - The device that was created.
:ref:`device_ref` - The device that was created.

**Throws:**
``UnknownDeviceTypeException`` - If a Device Handler with the specified name and namespace is not found.

``IllegalArgumentException`` - If the ``deviceNetworkId`` is not specified.

``SizeLimitExceededException`` - If this SmartApp already has the maximum number of children allowed (500).

----

Expand Down Expand Up @@ -586,7 +609,8 @@ Returns the URL of the server where this SmartApp can be reached for API calls.
getChildDevice()
----------------

Returns a device based upon the specified device network id. This is mostly used in service manager SmartApps.
Returns a device based upon the specified device network id.
This is mostly used in Service Manager SmartApps.

**Signature:**
``DeviceWrapper getChildDevice(String deviceNetworkId)``
Expand All @@ -602,7 +626,8 @@ Returns a device based upon the specified device network id. This is mostly used
getChildDevices()
-----------------

Returns a list of all child devices. An example use would be in service manager SmartApps.
Returns a list of all child devices.
An example use would be in Service Manager SmartApps.

**Signature:**
``List getChildDevices(Boolean includeVirtualDevices)``
Expand Down
1 change: 1 addition & 0 deletions smartapp-developers-guide/parent-child-smartapps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ Tips and best practices

- Think carefully about creating more than one level of parent-to-child relationships, as it may negatively impact usability and create unneeded complications.
- Sharing ``state`` or ``atomicState`` between parent and child SmartApps is not currently supported.
- The number of children a SmartApp may have is capped as documented in the :ref:`parent_child_count_limit`.

----

Expand Down

0 comments on commit b16db96

Please sign in to comment.