Friday, February 26, 2021

Feedback mechanism as an independent application:

 Requirements for feedback collection system as a stored application: 

Problem statement: Feedback is not the onus of component owners. It is a utility that spans components and features.  While they may choose to collect feedback at specific scopes, a utility can bring drag and drop ease of use while permitting those features to view the reports only later. How do we write an application for feedback collection? 

Solution: Since the feedback system does not take away any of the functionality of the underlying system and merely adds an option to the user, it can be packaged as an application that gives this option to the user. If it is part of the toolbar or available as a floating action button, it will be tiny as well as ubiquitous. All components expect a like or a quantitative rating or a qualitative input or a file attachment as convenient forms of user feedback. The scoped application merely collects them in a table that is unobtrusive to others in terms of functionality, performance, and security. Let us take a closer look at this feedback design system from the collection point of view. 

When the feedback collection is consistent across all components, it tends to have a schema. This data can be collected in a table and the size of the table can grow arbitrarily. Creating instances of the table scoped to the component, feature, or product for which the feedback is provided allows the number of such feedback tables to be finite and each allowed to grow as much as their usages. But when it is part of a scoped application, the size can grow considerably.  

The table itself must be generic to hold the most frequent forms of input. Extensions can allow customizations to be stored. The source information such as a Uniform Resource Locator of the page on which the control was displayed along with the query parameters become useful to track. A binary outcome might be sufficient for machine learning-based analysis later. 

The data from the transactional database can be rolled from the database to a data warehouse for periodic rollover of transactional tables. The feedback service would be rolling up the feedback and inserting it as a new record while deleting the archived ones. The historical information on the feedback is also useful for analytics which can independently be implemented with read-only reporting stacks.  This calls for a warehouse that can support a variety of reporting stacks. Archival of transactional records to keep the size limitation for the online transactional feedback system is sufficient even if the warehouse does not exist. The warehouse merely helps with the reporting stack to be read-only and independent from the online transactional tables. 

The front-end can be a JavaScript floating action button or a toolbar button. It can be written with Vue as JavaScript reactive framework. It could adopt the same theme as the overall theme of the application where the control is displayed.  

Conclusion: Separating the functionality of a feedback loop into an application and deploying it with other components and features of a web application is possible and beneficial to their focus. 

 

Thursday, February 25, 2021

Feedback Mechanisms continued...

 Telemetry and its storage: 

Problem statement: We discussed a mechanism to collect feedback from the users of a software application. This article follows up with the storage for the feedback. 

Description: When the feedback collection is consistent across all components, it tends to have a schema. This data can be collected in a table and the size of the table can grow arbitrarily. Creating instances of the table scoped to the component, feature or product for which the feedback is provided allows the number of such feedback tables to be finite and each allowed to grow as much as their usages.  

Some feedback could be quantitative, others could be qualitative or both. They can even become full-fledged surveys that can be customized. Others can be as short as a specially crafted Uniform Resource Locator that provides all the relevant information via previously crafted query parameters. A binary value might be sufficient in such a feedback. If only metrics were collected, it could be saved in Telegraf, InfluxDB and Grafana stack.

If the content varies a lot, it can be saved in key-value stores or non-relational data with as much convenience as that of a database. When this is collected from a multi-tenant's software, even the databases are separate for each customer. A collection service along with a load-balancer or a high-availability cluster mode storage nicely enables the scale out for an increase in traffic. The use of a service is favored even by platforms like Kubernetes that bring the best practice for hosting infrastructure. 

The data from the transactional database can be rolled from the database to a data warehouse for accumulation. In the absence of a warehouse, the services would be rolling up the feedback and inserting it as a new record while deleting the archived ones. The historical information on the feedback is also useful for analytics which can independently be implemented with read-only reporting stacks.  This calls for a warehouse that can support of a variety of reporting stacks. Using a warehouse also supports replacing the database with a data pipeline involving event processors. The use of event processors and the standard stream querying libraries is well-known for pipeline operations. These libraries support both querying and extract-transform-load operations because they deal with one event at a time.  

A data warehouse can be supported in the cloud with the help of virtual data centers. One such popular warehouse supports data ingestion in the form of JSON from data pipelines. The ability to perform queries over this warehouse follows the conventional Online Analytical Processing model and serves the feedback mechanism very well. Data virtualization libraries that make querying simpler, like Presto, is not needed because the data warehouse supports both querying and storage with a traditional query language. The data is also expected to be consistent between the tenants so there is no need for alternative solutions for any custom processing.    

Conclusion: The information from feedback can seamlessly make its way through collection services, storage tiers and reporting stacks for an end-to-end completion of a feedback cycle to improve the software offering. 

 

Wednesday, February 24, 2021

Feedback Mechanisms

 

Introduction: The User Interface for software applications is designed for human interaction, ease of use and convenience. One aspect of building this engagement is the collection of feedback from the user on the relevancy, timeliness and appropriateness of content. Most users will not hesitate to provide a feedback when they have genuinely come across a satisfying experience. The software maker has the options to provide some utilities to collect this feedback at those anticipated moments during the engagement process. For example, when a work note appears on a service request and it has mitigated a concern for the user, a feedback link will be appropriate to be positioned next to the work note such that user can enter her feedback. This article delves into the considerations surrounding feedbacks, their number, format, content and their tradeoffs.

Description: The most common form of feedback is a rating mechanism. A simple count of one to five stars is sufficient to capture the sentiment of the user if a particular interaction was satisfactory.  This is a quantitative assessment which can be followed up with a textbox for qualitative feedback. Together, they capture just enough information to help the maker improve or deprecate certain features and workflows. Such feedback mechanism finds great appeal at customer touchpoints that are mission critical and with high business value. It could be used at the end of a training or it could be requested at the end of a job submission. Long forms are sometimes a necessary evil in some workflows and the feedback mechanism is not only cathartic to the user but also ways for the maker to learn how to evolve the workflow in subsequent versions.

Not every feedback mechanism can include a survey or a form by itself. Some may simply be a yes or no answer. Others may involve a link to the user where the action of clicking the link alone is sufficient because it has been constructed with query parameters that convey all the relevant information to the maker. Feedback also can be solicited from devices other than the desktop by means of one-time messages to the user's personal handheld mobile devices. 

The opportunity to provide feedback is appealing to many feature teams but they are pigeon-holed in delivering what is required from their component. The customer, on the other hand, may find such request one too many especially if they are forced to become selective because it taxes them when the overall engagement could be considered laborious. Usability often finds feedback mechanism as conflicting with its goals. The right number of feedback requests at the right touchpoints in the customer engagement is undeniably beneficial but the process of making it just right is fraught with many players, processes and prone to negligence from periodic reviews. Most feedback mechanisms and the policies associated with them do not even appear in the functional design or the architecture of a component or feature. Developers arguably ask why the feedback cannot be a floating control that can latch on to any page shown from the web-application rather than the component having to provide or implement a suitable tactical utility. Test teams may even deprioritize it from their test plan because telemetry cannot be forced on the user. Finally, the collection of feedback is significantly dependent on participation which may vary from audience to audience if not for the vagaries of the components in the overall product. 

Indeed, interceptor mechanisms and floating controls are an incredible strategy for feedback collection because they remain perpetually available and bring consistency across the use of the product while relieving the feature teams from re-inventing the wheels. Where then can we find such examples of feedback collection if it weren't overloaded with other telemetry requirements. The commercial software products customer designed for consumer space is a great arena to find such examples.

Software such as MOpinion, InMoment, Clarabridge, Qualtrics, Feedbackify, Verint Foresee, OpinionLab, HubSpot, Survicate, and SurveyMonkey provide a breath-taking diversity in such techniques. Their offerings can be categorized as Voice of the customer tools, survey tools, Online Review tools, User testing tools, Visual feedback tools and community feedback tools. The right tool for the right feedback gathering requirement makes the process effective and efficient. At the same time, if there were no necessity to collect user feedback and if it could be learned by some other technique, that would not only relax the requirements but also enable the system to come up with an authoritative metric that would not be susceptible to user participation. One must however be careful to not relate cause and effect with this kind of a strategy since that will lead to errors which may skew the metric.

Conclusion: From the simple to the elaborate, feedback mechanisms provide various enhancements to a customer’s experience. Some of these are referred to in this article but the must all be enticing to the customer.



Tuesday, February 23, 2021

Retry

 The case for Retry in JavaScript errors: 

 

Problem statement: Scripts written for DevOps are susceptible to intermittent failures that can be overcome with retries. For example, a database may not be reachable within the limited timeout that is usually set for scripts. Nested commands can be called that might each take their own timeout. Such errors do not occur under normal conditions, so they escape the functional tests. If a limited number of retries were to be attempted, the code executes successfully, and the issue does not recur. Retry also has the side-effect that it reduces the cost of detection and investigation to other spurious errors from logs, incidents and false defects. How do we handle intermittent failures is the subject of this article. 

 

Solution: The implementation of the retry is independent of the callee. Scripts are not written in programming languages like Java where the callee can be standardized to a Runnable. Scripts also do not mandate a conformance to a convention across their usages. The most common form of a callee is a typical JavaScript function. The invocation of the function could result in a timeout exception, so the retry only works with the use of try-catch handler. 

The catch handler could specifically look for the timeout exceptions and handle it accordingly where the callee is retried. The number of retries for the callee is set to a small and finite number such as ten. 

The retry logic ensures that the result returned from the retry is that of the callee otherwise it propagates unknown exception. The use of retry is only for known exceptions and the unknown exceptions pass through to the caller. Therefore, the behavior is the same as that of the callee. If the results are returned as undefined in error conditions by the callee, it must also be returned as undefined by the retry. 

The Retry script can optionally log the number of attempts to help find the root cause for the intermittent errors and to ensure that they do not go undetected for a long time. Such automatic handling of intermittent failures along with the transparency of what those errors were will likely bring down the overall number of exceptions encountered in a system from operations. This will improve the health of the system and the metrics as well as reports that are used in the monitoring dashboards.  

The retry logic can be made flexible and reusable to include numRetries and delayMillis between the retries on the calleeThese parameters can be used with the initialization of the retry function object or passed in as parameters. 

Since the retry addresses a broad range of callee and their intermittent failures, it could be put in a library with the callee passed as parameter. The reuse of the retry logic brings consistency and possible instrumentation for future investigations and their benefits. 

 

Conclusion: Retry logic is a simple and effective technique to improve the DevOps and bring down the number of errors and exceptions substantially. 

 

// Sample code 

// for retries with exponential backoff 

var RetryUtil = Class.create(); 

RetryUtil.prototype = { 

initialize: function() { 

this.numRetries  = 10; 

this.delayMillis = 0; 

this.toleratedExceptions = []; 

}, 

  

retryOperation: function (fnnumRetriesdelayMillistoleratedExceptions) { 

if (numRetries) { this.numRetries = numRetries; } 

if (delayMillis) {this.delayMillis = delayMillis; } 

if (toleratedExceptions && toleratedExceptions.length == 0) {this.toleratedExceptions = toleratedExceptions;} 

for (var r = 0; r < this.numRetries; r++) { 

try { 

return fn.call(); 

} catch (e) { 

for (var i = 0; i < this.toleratedExceptions.lengthi++) { 

if (e instanceof this.toleratedExceptions[i]) { 

if (this.delayMillis > 0) { 

gs.sleep(delayMillis * Math.pow(2, r)); 

} 

continue; 

} 

} 

throw e; 

} 

} 

}, 

  

type: 'RetryUtil' 

};