Apollo cache is getting reset back to old data - graphql

I'm building an Expo mobile app using AWS AppSync and Apollo and I've got an intermittent but very serious issue with the cache getting corrupted, or at least not being updated properly. Unfortunately, because I'm using AppSync and I want the offline capability, I can't upgrade to the latest Apollo client, so as a result the data is stored in Redux, there are 4 top-level keys: offline, rehydrated, appsync and appsync-metadata.
This is what I expect to happen:
GraphQL query for a "project" returns the correct data
This data is written into the cache. In particular, I'm expecting that in appsync.ROOT_QUERY there'll be an entry for the project, something like getProject({"input":{"id":"project-7"}}) plus a top level entry in appsync for the project with all of its properties.
When I do execute a mutation, I'm expecting the project entry to be updated.
Since the project is updated, I'm expecting the UI to be refreshed reflecting the updated data.
Most of the time, this happens exactly as above. However, sometimes something happens to the cache. I'm not sure exactly what, but it gets into a weird state and I can't fix it.
Here are the symptoms:
When I start the app, the cache is initialised to an "old" state, one that doesn't include the query for project-7 even though I had queried for it just moments before killing the app.
When I do a search for project-7, it then adds the getProject...project-7 query to the cache and an entry for project-7, but for some reason doesn't seem to have all the fields.
When I do a mutation, there's an AAS_WRITE_CACHE which actually removes the getProject...project-7 entry from the query cache! The mutation succeeds though, I can see that the data in the AppSync server is updated, and the client doesn't log any errors anywhere.
The UI does NOT update.
I tried adding an update to the mutation so that I could update the cache myself, but when I execute const data = proxy.readQuery({ query: ProjectQuery } ... ) (specifying project-7), it throws an exception to say that it can't find that query, so I can't update the project. If I manually re-get the project, then everything works again until the next mutation.
What's really difficult, is that once my app is in this state, I can't work out how to fix it. I've tried client.resetStore() but it just gets rehydrated. I've tried calling AsyncStorage.clear() and then stopping the app and restarting it, but that doesn't work either. How can this be? Where is it storing the data?
It's worth saying again that on most of the devices I've tested it on (both Android and iOS), it works for days without any problems, but on one Android device in particular, it happens once every day or two. Twice I've been able to fix it using the "Clear Async storage" in the React Native Debugger, but now even that doesn't seem to fix it.
So, here are my questions:
Can anyone suggest what might be causing the cache to get into this weird state? Or how I can try and track down the problem.
Where is it storing the data that it then puts back? There are snapshots of the cache in appsync-metadata but surely they should also be removed when I clear all the AsyncStorage?
I'm really stuck!!
PS Here are the relevant (I think) packages I'm using:
"apollo-client": "^2.5.1",
"aws-amplify": "^1.1.27",
"aws-amplify-react-native": "^2.1.11",
"aws-appsync": "^1.7.2",
"aws-appsync-react": "^1.2.7",
"expo": "^33.0.0",
"graphql": "^14.3.0",
"graphql-tag": "^2.10.1",
"react": "16.8.3",
"react-apollo": "^2.5.8",

Related

GraphQL Elixir/Phoenix API: Socket hang up with large json response

New to Elixir/Phoenix and GraphQL. I have created a simple API that retrieves "drawings" from a PostgreSQL database. The table consists of an "id" (uuid) and "drawing_json" (text). In the table is one row with a json string of about 77Kb. My schema and queries are defined using Absinthe. I have 1 query called "all_drawings" which resolves and reaches out to the Repo and pulls in all drawings. When using postman to call this API, the following query works fine:
{
allDrawings
{
id
}
}
However, when I try to return the json field as well the postman request times out and I get a "socket hang up" error.
Looking at the Debug Console in Visual Studio Code, I can see the query gets the data from the db just fine and almost immediately. Something seems to be happening though in returning it to the client that I can't detect. No errors are thrown. Any ideas? Not sure what information will help but happy to provide more.
A colleague helped me find the fix. Not sure why this is (maybe someone can elaborate), but the issue was with trying to run it in Visual Studio Code. Previously, I set up the run task in launch.json and would click the run button to start debugging my application. This would cause the aforementioned crash every time. When I went to the terminal and ran the "mix phx.server" command, everything worked fine. Not sure if the hang up is with Visual Studio Code or the ElixirLS extension when using the IDE to debug. But starting the application through the command line allowed me to use postman to hit the api and retrieve the data just fine. I'm very new to the Elixir/Phoenix world so I'm unable to draw a more intelligent conclusion as to why this happens.

After upgrade from Dynamics CRM 2011 to CRm 2016 experiencing weird issue with forms and plugins

Client company just upgraded to 2016 from 2011. I've been testing the plugins to make sure they all still function and I've finally (after much frustration) figured out what is happening, but no idea why or how to resolve this.
I have several plugins and they all function exactly as expected - as long as the updates to the data are not run through the forms.
Let me explain:
I have plugins (Synchronous) that trigger on a change to a field. If the field is changed via a workflow, or some other coded process, everything runs just fine.
But when I update the field on the form it's self. It fails with a very generic error (below).
I support a couple of other clients already on 2016, and I'm not experiencing this same problem. So I'm not even sure where to begin. I've been going crazy here the last couple of days to check the code. But it only happens when updating the field on the form. Every other method of updating the data that I have tested works with no errors.
I also have another issue. When the field is updated (through a test workflow), it runs and updates a child record. The child record then has a workflow that runs to deactivate the record. The workflow says it ran and deactivated the record, but it never deactivates).
Anyway. if ANYONE has ANY idea at all about what could be causing this. I would love to hear it. I'm at my wits end on this.
Thank you in advance.
I've tested the code and had it run successfully, as long as I don't update the field through the form. To test this I created some test workflows that update the data, they successfully run and the plugins fire off with no problems.
EntityReference contact =
(EntityReference)preImageEntity.Attributes["ipmahr_contact"];
QueryExpression cn = new QueryExpression("ipmahr_recertification");
cn.ColumnSet = new ColumnSet("ipmahr_contact", "statecode");
cn.Criteria.AddCondition("ipmahr_contact", ConditionOperator.Equal,
contact.Id);
cn.Criteria.AddCondition("statecode", ConditionOperator.Equal, 0);
EntityCollection results1 = server.RetrieveMultiple(cn);
if (results1.Entities.Count > 0)
foreach (Entity a in results1.Entities)
{
a.Attributes["ipmahr_deactivaterecertificationrecord"] = true;
server.Update(a);
}
The code is pretty straightforward in most cases, and works fine as long as things aren't updated on the form.
Here is the error: Exception: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]: System.ServiceModel.CommunicationObjectFaultedException: #595EB751 (Fault Detail is equal to Microsoft.Xrm.Sdk.OrganizationServiceFault)., Correlation Id: fd1a79ca-c846-407b-b578-ac9207d6dd0e, Initiating User: 274d55dc-3f4d-e811-b30f-0050569142af Exiting Recertifications.Main.DeactivateUsedRecertificationsonEndDateChange.Execute(), Correlation Id: fd1a79ca-c846-407b-b578-ac9207d6dd0e, Initiating User: 274d55dc-3f4d-e811-b30f-0050569142af
New information. I have found that not all the plugins I've written have an issue on this server. This is good. But I also found that there is a commonality on those plugins that do fail.
Any plugin using a Query Expression fails with the generic error. Adding robust error checking didn't show anything (once error checking was added, it just didn't run anything, and didn't produce any errors in the logs). Trace logs didn't show anything significant either.
So now I'm wondering if there is something in the way the Query Expression is formatted, or if there is an issue with the SQL. I mention SQL because I found this morning that if I create fields too fast, I get a generic SQL error. Wait a minute and I can create new fields without a problem.
I think it likely that this plugin is not actually failing based on the error you are receiving and the fact that it happens conditionally. More likely, your server.Update(a); call is resulting in a failure within a secondary plugin or workflow action triggered by update of the Recertification record.
- Comment out that line and verify that the plugin works
- See if you can reproduce a failure by directly updating that field on the Recertification record
- Review plugin/workflows running against the Recertification entity
Most likely this has one of the following root causes:
- A security issue based on different executing users between the form update or workflow update
- Other tangential fields are being updated by one or the other of those two methods which subsequently cause different behavior in a secondary plugin/workflow

"New version available" with service worker and sw-precache

I'm trying to use sw-precache, but I must be doing something wrong!
I'm mostly using the demo code available from the github repo and can't seem to get updates to the app to come through. Once it's cached the first time, it never checks for new versions.
I was expecting that when I publish a new service worker, the browser would request the new service worker and update the cache accordingly in the background. Then using the registration code in the example, I would be able to prompt the user to refresh and get the latest version from their newly refreshed cache.
Would really appreciate if someone could please point me in the right direction.
Example
To demonstrate the problem, I've created an isolated example here:
https://github.com/stevenocchipinti/sw-precache-demo
The example uses a basic skeleton from create-react-app which has a built in build task which take care of fingerprinting the filenames, etc.
I suspect the problem is with me caching everything by using the following sw-precache config:
{
"staticFileGlobs": [ "build/**/*.*" ],
"stripPrefix": "build/"
}
There are more accurate steps in the repo's readme, but the basic steps I'm taking to reproduce the problem are as follows (with my probably incorrect expectations).
Steps and Assumptions
Browse to the app for the first
I should see Content is now available offline! in the console
Reload the page
The message in the console should not appear again because the service worker is installed, but the page should still work.
Go offline and reload the page
The page should still work
Make a visible change to the source code
Rebuild (run the build task and sw-precache)
This is where my understanding must be wrong
Reload the page
The service worker should update the cache in the background
When its done, you should see New or updated content is available. in the console
The actual visible changes should not be visible until the next reload
Reload the page again
The browser will use the new cache this time around
The changes should be visible now!
There shouldn't be any messages in the console
The problem
Once the app has been cached initially, it will never update unless you unregister the service worker or force a reload.
I'm not sure how to make this work - any help would be greatly appreciated!
After replicating your development hosting environment, I can see that you're serving your service-worker.js file with a browser HTTP cache lifetime of one hour:
There's more information as to why this is leading to the behavior you're seeing, along with best practices, in this previous answer. As mentioned at the top of that answer, browsers plan on changing their behavior to stop honoring the HTTP cache for the service worker file by default, mainly due to the type of confusion that you're experiencing here. For the time being, though, the production versions of both Chrome and Firefox continue to honor those headers.

Laravel 5.1 randomly dropping session data

I have a strange issue with a Laravel 5.1 application.
Intermittently, it’s dropping session data. I’m detected this by writing some middleware that writes the contents of the session for that request to the log file. Although the session ID (Session::getId()) doesn’t change, the value of _token in the session data retrieved with Session::all() does.
As I say, this happens intermittently. I can refresh the same URL multiple times, and then randomly on one refresh the session data’s gone, and the _token value’s different from the previous requests.
What would cause this? I’ve also noticed the flash object isn’t in the “dropped” session data.
Below is a snippet of the log. You can see the content of the session_data key randomly changes “shape” in the last two lines, but the session ID remains constant.
Also, not sure if it’s pertinent, but I have DebugBar enabled.
UPDATE: Through debugging, I’ve found that on some page loads the session is completely empty, as in, no _token (hence a new one getting generated). Nothing.
If you're using the file driver, you could run into race conditions on concurrent requests. The file then gets truncated, Laravel can't read it, so it refreshes the session. Race conditions can also lead to a symptom where something you're putting to the session just doesn't get put. This tends to be random, so it's very hard to debug. According to the Laravel team, this is a known limitation of the file driver and it does not appear to be getting fixed, so I would suggest using a different driver. This would fix your issue of random session refreshes, but it still introduces a possibility of making a change to the session that doesn't get added. As far as I know, at this point with Laravel 5.1, you'll have to manage that yourself.
Somehow your session data is too long and being truncated. If you're using the database driver (haven't tested other drivers), and you try to save session data that's longer than the field length, then subsequent requests won't be able to pull from this session, and you'll wind up with a new session. If this issue is happening randomly with very short session data, then it's probably the cause listed above.
If you use Linux, Try using Redis (http://redis.io) as session / cache manager in laravel. I had some issues in the past with text / cookies and laravel in some servers. When I instaled Redis I had no problems anymore.
More info: https://laravel.com/docs/5.1/redis
Using a different driver like memcached did not solve the problem for me.
Here is a package that implements session locking which works and very simple to incorporate in your projects.
https://github.com/rairlie/laravel-locking-session

Cannot re-create app due to error "This Firebase URL is not available"

I decided to try out Firebase hosting and wanted to start fresh so I deleted my one and only app, but when I tried to create a new app with the same name I was unable to due to the error:
"This Firebase URL is not available"
I can only guess this is because of caching of app names/URLs? Hopefully it will become available (unless someone else beats me to it) after some timeout? Any info from others who have experience with this issue or otherwise know the answer is appreciated!
Not sure whether this is the right place to ask although Firebase suggest coming to SO because they apparently monitor Firebase-related questions closely according to their website.
Thanks!
Once you delete a Firebase URL, it is permanently unavailable. It cannot be recovered.
During confirmation, you should see a message like this, which explains in detail:
This stems from a number of abuse vectors that are possible by misappropriating a project id that the prior owner believes is deleted and could still have apps/releases in the wild attached to the defunct backend. Since compliance requires that we purge all data related to the project, including information about ownership, there's not even a way to restore one you personally deleted.

Resources