In my application, two users are alerted, who first click on the alert is who must save the object, but when the two click at the same time, one overwrites the other. I would not allow two users from changing the same data concurrently, how?
You could do the following:
Define a PFObject objectSaved that has a counter field. Initialize the counter to 0.
Trigger a beforeSave action (see here) in cloud code that is executed when one or both users try to save the same object. In the beforeSave action, atomically increment the objectSaved counter.
If only 1 user tries to save, the counter is now 1. If 2 users try to save at the same time (2 threads), one of them reads a counter value of 1, the other one a value of 2.
The user who got 1 is the first one, and she/he is allowed to execute the save operation. The other one is the second, and its save attempt is aborted with error.
It helps to read once more the link provided by NSNoob.
Related
I'm working on a Power Automate flow where the flow is supposed to connect to Planner, get the tasks which are due tomorrow and send a message to an MS Teams Channel.
I got the entire flow working except of one thing - getting the names of the person(s) whom the task is assigned.
Here's my current flow:
Getting the list of Tasks from Planner,
Filter those which have a Due Date set,
Filter the ones which have the Due Date tomorrow,
Get the Name of the Task Creator using Get User Profile,
Send the data into an MS Teams Channel.
This all works perfectly fine. However I also need to get the names of the Assigned users. I understand that they come as an array. And when I try to add it to the same Get User Profile it's getting wrapped into an unnecessary "Apply to Each" which breaks everything.
Does anyone have a clue how this can be solved? Basically I need only 1 Assignee as we are not going to assign the same task to more than 1 person.
Any help would be much appreciated!
In order to avoid the loop (which is also a valid approach, long story) then you can use an expression to get the first (in case there are multiple) assigned user.
This is an example where you don't need to loop ...
... you can see I've initialised a (string) variable at the top which will hold the user ID GUID.
... then further down in the Set Assigned To operation, this is the expression I use ...
item()?['_assignments'][0]['userid']
That gets the first user and then the associated userid property. You can then pass that into the Get user profile (V2) task ...
Obviously, you need to adapt that to your flow but I hope that makes sense.
In my Parse app, I want Users to have access to an audio file only ten times.
Once they have listened to it 10 times, I don't want them to be able to access it.
Essentially, from my current understanding about Parse, I would have to somehow remove them from a role while keeping some kind of secure counter somewhere.
Is there a clean simple way to do this?
Based on your comment about around 100 items, I think the easiest way to handle this is with something akin to a join table.
Essentially, you will have a new Parse database class, call it 'Uses', that tracks how many uses of an item each user have. It will have the following fields:
user (Pointer): The user in question
resource (Pointer): The resource (audio file they have accessed)
count (Number): The number of times they have used the resource
Your logic in the app should be as follows:
Query the Uses table for items where user = current user and resource = requested resource
If doesn't exist, create one and set the count = 1
If does exist, check the count
Count < 10? Play the item
Count > 10? Throw an alert
If security is paramount, you could do this via a Cloud Code call instead to prevent an unscrupulous (but very very smart) user from altering their entries in the Uses table. It depends on how paranoid you need to be.
Hope that helps!
My Golang code gets different records from the database using goroutines, and increments the value in a determinated field in the record.
I can avoid the race condition If I use Mutex or Channels, but I have a bottleneck because every access to the database waits until the previous access is done.
I think I should do something like one Mutex for every different record, instead one only Mutex for all.
How could I do it?
Thanks for any reply.
In the comments you said you are using Couchbase. If the record you wish to update consists of only an integer, you can use the built in atomic increment functionality with Bucket.Incr.
If the value is part of a larger document, you can use the database's "Check and Set" functionality. In essence, you want to create a loop that does the following:
Retrieve the record to be updated along with its CAS value using Bucket.Gets
Modify the document returned by (1) as needed.
Store the modified document using Bucket.Cas, passing the CAS value retrieved in (1).
If (4) succeeds, break out of the loop. Otherwise, start again at (1).
Note that it is important to retrieve the document fresh each time in the loop. If the update fails due to an incorrect CAS value, it means the document was updated between the read and the write.
If the database has a way of handling that (i.e. an atomic counter built in) you should use that.
If not, or if you want to do this in go, you can use buffered channels. Inserting to a buffered channel is not blocking unless the buffer is full.
then, to handle the increments one at a time, in a goroutine you could have something like
for{
select{
value, _ := <-CounterChan
incrementCounterBy(value)
}
}
I'm trying to understand how to use the kFSEventStreamEventFlagEventIdsWrapped event flag with FSEvents.
According to the documentation, the flag is sent to registered instances when the event id counter wraps around, thus rendering previous event id obsolete.
Now let's imagine the following scenario:
I register for FSEvents in my application;
When done processing FSEvents (my application quits for instance), I save the last event id encountered while processing events to be able to replay changes from that id;
While my application is not running, the event id counter wraps around.
My question is: How am I supposed to know the counter wrapped around? (Thus requiring me to re-scan the whole directory structure.)
I now have an answer directly from Apple.
The scenario was wrong to begin with. When saving the last event id treated, you must also save with it the UUID of the event stream. An event id is valid only for a given event stream, which is identified by its UUID (see FSEventsCopyUUIDForDevice()).
Whenever the event id counter wraps around, a new event stream UUID is generated. So if you relaunch the app after the event id counter wrapped around, your stored last event id won’t be valid anymore, and you’ll know it as the event stream UUID won’t be the same.
If you encounter the kFSEventStreamEventFlagEventIdsWrapped flag, it means the counter wrapped around while your app was open. However, there’s nothing particular to be done. You should just be sure to get the new event stream UUID if you want to save the last event id.
EDIT:
Event IDs do not wrap.
Here is why: Suppose your machine generates 1 filesystem event per millisecond. This means it will generate ms_per_year=31536000000 filesystem events per year. So it will take more than 500 million years before the counter will wrap around the 64bit boundary.
>>> ms_per_year = 1000*60*60*24*365
>>> d64 = 2**64
>>> d64/ms_per_year
584942417L
If kFSEventStreamEventFlagEventIdsWrapped is set, it means the 64-bit event ID counter wrapped around. As a result, previously-issued event ID's are no longer valid arguments for the sinceWhen parameter of the FSEventStreamCreate() functions.[1]
Next time your should use kFSEventStreamEventIdSinceNow for FSEventStreamEventId and you must rescan all directory.
I recently moved my background synch downloads to a view controller and need some advice on how to best handle them asynch. I have written all the code to show a progressview as the download occurs but as you might have guessed it's not that simple. Here's how it works.
user sees a tableview with two entires one for each database. they can press a button to download the database and when the download starts that fires off the asynch URL connection,etc. This works to a certain extent however it's not that simple.
here's what i want it to do.
download the main update URL (works ok)
then download a secondary URL.
then apply the first URL content to the sqlite store (code written for that)
then apply the 2nd URL content to the sqlite store (code written for that)
(All the while showing progress to the user)
when the downloads were synch it was easy as i just waited for them to finish in order to fire the next activity off but when using the asynch method i'm struggling with how to get them to wait. Step 3 depends upon step 1 finishing and step 4 depends on step 2 finishing and overall success relies on all finishing. step 4 needs to wait for step 3 to finish otherwise the database locks will cause a clash.
the second complication is that if the user presses the second button while the first is downloading then steps 3, 4 will clash if they execute at the same time as the first row is accessing the database.
Has anyone done anything similar and if so what was the strategy you used to manage the flow of events.
Also i wanted to wrap this all up in a backgroundTask with ExpirationHandler so it would survive the user pressing the home button... but the delegate methods don't get called when i do that.
Ok Here is what i did to fix the problem.
Created an NSOperationQueue
Added the URL operations as NSURLInnvocationOperations
3.waited until the URL operations were complete (waituntilalloperationsarefinished).
Then set the max concurrent count to 1 which forced the subsequent database operations to execute in series one after the other and thus prevented SQLite from locking it's self out.