<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
<base href="https://issues.jboss.org">
<title>Message Title</title>
</head>
<body class="jira" style="color: #333333; font-family: Arial, sans-serif; font-size: 14px; line-height: 1.429">
<table id="background-table" cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background-color: #f5f5f5; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt" bgcolor="#f5f5f5">
<!-- header here -->
<tbody>
<tr>
<td id="header-pattern-container" style="padding: 0px; border-collapse: collapse; padding: 10px 20px">
<table id="header-pattern" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt">
<tbody>
<tr>
<td id="header-avatar-image-container" valign="top" style="padding: 0px; border-collapse: collapse; vertical-align: top; width: 32px; padding-right: 8px" width="32"> <img id="header-avatar-image" class="image_fix" src="https://static.jboss.org/developer/gravatar/1cc65a76f8140cf84d31e7f165c1ff1e?d=mm&s=48" height="32" width="32" border="0" style="border-radius: 3px; vertical-align: top"> </td>
<td id="header-text-container" valign="middle" style="padding: 0px; border-collapse: collapse; vertical-align: middle; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px"> <a class="user-hover" rel="wtrocki" id="email_wtrocki" href="https://issues.jboss.org/secure/ViewProfile.jspa?name=wtrocki" style="color:#0052cc;; color: #3b73af; text-decoration: none">Wojciech Trocki</a> <strong>updated</strong> an issue </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td id="email-content-container" style="padding: 0px; border-collapse: collapse; padding: 0 20px">
<table id="email-content-table" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; border-spacing: 0; border-collapse: separate">
<tbody>
<tr>
<!-- there needs to be content in the cell for it to render in some clients -->
<td class="email-content-rounded-top mobile-expand" style="padding: 0px; border-collapse: collapse; color: #ffffff; padding: 0 15px 0 16px; height: 15px; background-color: #ffffff; border-left: 1px solid #cccccc; border-top: 1px solid #cccccc; border-right: 1px solid #cccccc; border-bottom: 0; border-top-right-radius: 5px; border-top-left-radius: 5px; height: 10px; line-height: 10px; padding: 0 15px 0 16px; mso-line-height-rule: exactly" height="10" bgcolor="#ffffff"> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand " style="padding: 0px; border-collapse: collapse; border-left: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #ffffff" bgcolor="#ffffff">
<table class="page-title-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt">
<tbody>
<tr>
<td class="page-title-pattern-first-line " style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; padding-top: 10px"> <a href="https://issues.jboss.org/browse/AEROGEAR" style="color: #3b73af; text-decoration: none">AeroGear</a> / <a href="https://issues.jboss.org/browse/AEROGEAR-8284" style="color: #3b73af; text-decoration: none"><img src="cid:jira-generated-image-avatar-f34b7029-dcc8-4b49-8dbf-5579e81d60eb" height="16" width="16" border="0" align="absmiddle" alt="Epic" style="vertical-align: text-bottom"></a> <a href="https://issues.jboss.org/browse/AEROGEAR-8284" style="color: #3b73af; text-decoration: none">AEROGEAR-8284</a> </td>
</tr>
<tr>
<td style="vertical-align: top;; padding: 0px; border-collapse: collapse; padding-right: 5px; font-size: 20px; line-height: 30px; mso-line-height-rule: exactly" class="page-title-pattern-header-container"> <span class="page-title-pattern-header" style="font-family: Arial, sans-serif; padding: 0; font-size: 20px; line-height: 30px; mso-text-raise: 2px; mso-line-height-rule: exactly; vertical-align: middle"> <a href="https://issues.jboss.org/browse/AEROGEAR-8284" style="color: #3b73af; text-decoration: none">Add ability to enable, detect and resolve data conflicts when working offline</a> </span> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand wrapper-special-margin" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #ffffff; padding-top: 10px; padding-bottom: 5px" bgcolor="#ffffff">
<table class="keyvalue-table" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt">
<tbody>
<tr>
<th style="color: #707070; font: normal 14px/20px Arial, sans-serif; text-align: left; vertical-align: top; padding: 2px 0">Change By:</th>
<td style="padding: 0px; border-collapse: collapse; font: normal 14px/20px Arial, sans-serif; padding: 2px 0 2px 5px; vertical-align: top"> <a class="user-hover" rel="wtrocki" id="email_wtrocki" href="https://issues.jboss.org/secure/ViewProfile.jspa?name=wtrocki" style="color:#0052cc;; color: #3b73af; text-decoration: none">Wojciech Trocki</a> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand issue-description-container" style="padding: 0px; border-collapse: collapse; border-left: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #ffffff; padding-top: 5px; padding-bottom: 10px" bgcolor="#ffffff">
<table class="text-paragraph-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 2px">
<tbody>
<tr>
<td class="text-paragraph-pattern-container mobile-resize-text " style="padding: 0px; border-collapse: collapse; padding: 0 0 10px 0"> <span class="diffcontext">WIP<br><br>h3. High level targets<br><br>Enable framework for effective conflict resolution on client and server.<br>Enable full traceability for conflict resolution<br>Allow developers to define what conflict means and how it's detected<br>Build sample application that (integrate with current sample application <br><br>h3. Non target<br><br>- Provide comprehensive query mechanism working with conflict resolution.<br>- Provide data focused conflict resolution (data from different sources)<br><br>h3. Technical information<br>h4. Enablement<br><br>Server side is dictatic conflict resolution policies. Users can provide default state provider in the configuration:<br><br>{code}<br> {<br> conflictProvider?: new VersionedObjectState() <br> }<br>{code} <br><br>By default conflict provider is `VersionedObjectState` which implements `version` field conflict detection.<br><br>Outdated: <br>-Conflict resolution can be enabled on server by providing configuration options for both JavaScript SDK and server side:-<br><br>{code}<br> conflict: {<br> enabled: boolean<br> conflictStrategy?: (currentRecord: ConflictResolutionData, client: ConflictResolutionData) => ConflictResolutionData<br> }<br>{code}<br><br>-When conflict on server side is enabled it will by default defer resolution to server wins. Different strategies can be employed on both client and server but server side strategies have bigger priority over client (kinda obvious) call that out). Conflict resolution must be enabled on the client and by default it will process server side strategies. Users will be able to change conflict strategy on client but not disable it (as server really controls it)-<br><br>h4. Top level overview<br><br>Users interact with the conflict interface by calling hasConflict and next methods. They can import one of their predefined strategies or write their own. Conflict resolution is applied per resolver basis which gives great customization options.<br><br>h4. Operating on Object State on server<br><br>To effectively manage conflict resolution we need to have:<br><br>- effective way to iterate on object state (hashing, changing version)<br>- effective way to detect difference between version (collision aka conflict)<br><br>This can be achieved by following interface.<br>{code}<br>export interface ObjectState {<br> /**<br> *<br> * @param serverData the data currently on the server<br> * @param clientData the data the client wishes to perform some mutation with<br> */<br> detectConflict (serverData: ConflictResolutionData, clientData: ConflictResolutionData): ConflictInfo<br><br> /**<br> *<br> * @param currentObjectState the object wish you would like to progress to its next state<br> */<br> next (currentObjectState: ConflictResolutionData): ConflictResolutionData<br>}<br>{code}<br> <br>h4. Conflict resolution<br><br>Conflict resolution will use following interface:<br><br>{code}<br>(currentRecord: ConflictResolutionData, client: ConflictResolutionData) => ConflictResolutionData<br>{code}<br><br>h4. Communication between server and client<br><br>Server side will always return GraphQL error when conflict is detected thru interface. <br>Error will contain information about:<br>- Client and server state<br>- If conflict was resolved on server or deferred to client.<br><br>h4. Conflict resolution listeners on client<br><br>Client UI should be notified about the conflict being resolved. <br><br>h4. Conflict resolution and error strategy<br><br>Mutations error strategy needs to be specified in docs. Strategies like `none` cannot be employed since users <br>will not be able to see results coming back from server. Alternatively we should map server side error to different GraphQL error but this will mean that we will lose ability to notify users about conflict error for specific object.<br><br>h4. Conflict resolution and orphaned objects<br><br>Retrying policies should be employed on the ConflictLink to prevent from endless loop. <br>We should track conflicted data so there is no objects left in cache <br><br>h4. Special cases conflicts<br><br>Delete operations trigger conflicts that are not easily solvable using predefined strategies (due to fact that delete actually removes data). We need to apply strategy to clear the cache inside the link if delete happens. <br><br>h4. Subscription support<br><br>Conflicted data should not trigger subscriptions until data will be actually saved to the database. <br>Implementation details for this matter rely strictly on users performing publish subscribe operations, however we need to clearly document that as subscriptions can happen only when conflict is being resolved.<br><br>h4.</span> <span class="diffaddedchars" style="background-color:#ddfade;"> Error handling<br><br>To properly handle errors we may need to port retry error logic and make it work with conflict resolution. <br>Without it it will not be possible to get <br><br>h4.</span> <span class="diffcontext"> Implementation details<br><br>Versioning is already done in example app. All improvements should be done on JS-SDK level<br>!Screen Shot 2018-12-19 at 4.38.01 PM.png|thumbnail! <br><br>Data access methods are already defined and working.<br>Basic conflict resolution link is currently added to SDK:<br>https://github.com/aerogear/aerogear-js-sdk/tree/master/packages/sync/src/conflicts<br><br>Implementation ported from spike repo to server, however it may need to be changed to follow up new aproach:<br>https://github.com/aerogear/apollo-voyager-server/pull/15<br><br>h4. Packaging and deployment<br><br>Both client side and server will have different config and internal processing embedded into them. <br>If we identify some common or shared interface we may consider reusing server side package in client<br><br></span> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td class="email-content-main mobile-expand " style="padding: 0px; border-collapse: collapse; border-left: 1px solid #cccccc; border-right: 1px solid #cccccc; border-top: 0; border-bottom: 0; padding: 0 15px 0 16px; background-color: #ffffff" bgcolor="#ffffff">
<table id="actions-pattern" cellspacing="0" cellpadding="0" border="0" width="100%" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 1px">
<tbody>
<tr>
<td id="actions-pattern-container" valign="middle" style="padding: 0px; border-collapse: collapse; padding: 10px 0 10px 24px; vertical-align: middle; padding-left: 0">
<table align="left" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt">
<tbody>
<tr>
<td class="actions-pattern-action-icon-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 0; vertical-align: middle"> <a href="https://issues.jboss.org/browse/AEROGEAR-8284#add-comment" target="_blank" title="Add Comment" style="color: #3b73af; text-decoration: none"> <img class="actions-pattern-action-icon-image" src="cid:jira-generated-image-static-comment-icon-db26aa88-b405-4932-9aed-d51f6e49a1d0" alt="Add Comment" title="Add Comment" height="16" width="16" border="0" style="vertical-align: middle"> </a> </td>
<td class="actions-pattern-action-text-container" style="padding: 0px; border-collapse: collapse; font-family: Arial, sans-serif; font-size: 14px; line-height: 20px; mso-line-height-rule: exactly; mso-text-raise: 4px; padding-left: 5px"> <a href="https://issues.jboss.org/browse/AEROGEAR-8284#add-comment" target="_blank" title="Add Comment" style="color: #3b73af; text-decoration: none">Add Comment</a> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> </td>
</tr>
<!-- there needs to be content in the cell for it to render in some clients -->
<tr>
<td class="email-content-rounded-bottom mobile-expand" style="padding: 0px; border-collapse: collapse; color: #ffffff; padding: 0 15px 0 16px; height: 5px; line-height: 5px; background-color: #ffffff; border-top: 0; border-left: 1px solid #cccccc; border-bottom: 1px solid #cccccc; border-right: 1px solid #cccccc; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px; mso-line-height-rule: exactly" height="5" bgcolor="#ffffff"> </td>
</tr>
</tbody>
</table> </td>
</tr>
<tr>
<td id="footer-pattern" style="padding: 0px; border-collapse: collapse; padding: 12px 20px">
<table id="footer-pattern-container" cellspacing="0" cellpadding="0" border="0" style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt">
<tbody>
<tr>
<td id="footer-pattern-text" class="mobile-resize-text" width="100%" style="padding: 0px; border-collapse: collapse; color: #999999; font-size: 12px; line-height: 18px; font-family: Arial, sans-serif; mso-line-height-rule: exactly; mso-text-raise: 2px"> This message was sent by Atlassian Jira <span id="footer-build-information">(v7.12.1#712002-<span title="609a50578ba6bc73dbf8b05dddd7c04a04b6807c" data-commit-id="609a50578ba6bc73dbf8b05dddd7c04a04b6807c}">sha1:609a505</span>)</span> </td>
<td id="footer-pattern-logo-desktop-container" valign="top" style="padding: 0px; border-collapse: collapse; padding-left: 20px; vertical-align: top">
<table style="border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt">
<tbody>
<tr>
<td id="footer-pattern-logo-desktop-padding" style="padding: 0px; border-collapse: collapse; padding-top: 3px"> <img id="footer-pattern-logo-desktop" src="https://issues.jboss.org/images/mail/atlassian-email-logo.png" alt="Atlassian logo" title="Atlassian logo" width="191" height="24" class="image_fix"> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table> </td>
</tr>
</tbody>
</table>
</body>
</html>