I'm trying to add a limit to the amount of files a member can upload. But I can't seem to update the property of the member - that holds the value for how many files the member has uploaded - while the upload of multiple files is happening.
When the member uploads a file, I get the current IMember and increment the 'Count' value by one, and then save the member.
When the next file comes along, the 'Count' value has not been updated in the database yet, so the 'Count' stays unchanged when incremented.
I tried all sorts of ways to read/write the data before the 2nd file gets uploaded, but to no avail. Thought about writing a file to disk, but IO probably has the same issue as writing to the database, and I'd rather have all that data in the database anyway.
So, what to do? Am I doing it completely wrong in the first place, or is there a fancy solution for this kind of problem?
This is what I'd like to do:
var m = ApplicationContext.Current.Services.MemberService.GetById(member.Id);
int fileCount = m.GetValue<int>("fileCount");
fileCount += 1;
m.SetValue("fileCount", fileCount);
ApplicationContext.Current.Services.MemberService.Save(m);
The frontend js script throttles the amount of simultaneous uploads at a time to 3. If I upload 3 files, the count increases by 1. If I upload more files, the count is always 2 less than the amount of files uploaded.
I suspect that it is happening because the first 3 files that get added to the queue are "grouped" when sent with ms appart, whereas the remaining files are seconds appart, resulting in new requests with updated values.
The controller code is not complicated:
[HttpPost]
public JsonResult UploadFile(HttpPostedFileBase file, int parentId)
{
var member = Members.GetCurrentMember();
if (member != null)
{
var m = ApplicationContext.Current.Services.MemberService.GetById(member.Id);
int fileCount = m.GetValue<int>("fileCount");
fileCount += 1;
m.SetValue("fileCount", fileCount);
ApplicationContext.Current.Services.MemberService.Save(m);
}
return ToJson(1);
}
Please please please please do not update properties with a counter on members, content or media. it just leads to a complete copy of all property data on the specific item to be stored all over again. This very quickly increases the amount of rows in cmsPropertyData making your database grow really fast.
Counters should be maintained somewhere else, always. Consider a database table with two columns: member ID and upload count.
I tried creating a new table for storing just that data, but the 'refresh' of the database content still 'lags behind'. Tried it on both the main umbraco database and a secondary MySQL one.
Doesn't matter if I use the DatabaseContext or a new SqlConnection.
Its not about the connection, it is about the transaction. If you use a separate table, wrap the code that updates it in a transaction, that way any additional calls are blocked until the transaction completes, and that should take care of your issue.
Update member property inbetween file uploads
Hi,
I'm trying to add a limit to the amount of files a member can upload. But I can't seem to update the property of the member - that holds the value for how many files the member has uploaded - while the upload of multiple files is happening.
When the member uploads a file, I get the current IMember and increment the 'Count' value by one, and then save the member.
When the next file comes along, the 'Count' value has not been updated in the database yet, so the 'Count' stays unchanged when incremented.
I tried all sorts of ways to read/write the data before the 2nd file gets uploaded, but to no avail. Thought about writing a file to disk, but IO probably has the same issue as writing to the database, and I'd rather have all that data in the database anyway.
So, what to do? Am I doing it completely wrong in the first place, or is there a fancy solution for this kind of problem?
This is what I'd like to do:
Does it ever get updated?
Yes, after the first few httprequests..
The frontend js script throttles the amount of simultaneous uploads at a time to 3. If I upload 3 files, the count increases by 1. If I upload more files, the count is always 2 less than the amount of files uploaded.
I suspect that it is happening because the first 3 files that get added to the queue are "grouped" when sent with ms appart, whereas the remaining files are seconds appart, resulting in new requests with updated values.
The controller code is not complicated:
So you have a threading issue. the value is read from multiple threads, and the last one in is what you see as far as updating the value.
There are several ways to handle this, from putting a lock around the C# code to wrapping the code in a transaction to throttling on the client side.
That was my first thought as well, just didn't know how to get around it.
Not too happy about adding a lock, and throttling it on the client will just open a door to potentially exploit it =/
Please please please please do not update properties with a counter on members, content or media. it just leads to a complete copy of all property data on the specific item to be stored all over again. This very quickly increases the amount of rows in cmsPropertyData making your database grow really fast.
Counters should be maintained somewhere else, always. Consider a database table with two columns: member ID and upload count.
This is covered in the documentation about common pitfalls too: https://our.umbraco.org/Documentation/Reference/Common-Pitfalls/#using-umbraco-content-items-for-volatile-data
Yea, thought about that too..
I tried creating a new table for storing just that data, but the 'refresh' of the database content still 'lags behind'. Tried it on both the main umbraco database and a secondary MySQL one.
Doesn't matter if I use the DatabaseContext or a new SqlConnection.
Its not about the connection, it is about the transaction. If you use a separate table, wrap the code that updates it in a transaction, that way any additional calls are blocked until the transaction completes, and that should take care of your issue.
Cool, I'll give that a go. Thanks a lot :D
is working on a reply...